You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用strncpy复制char*数组遇段错误及memcpy用法问题求助

错误分析与解决方法

一、strncpy用法的错误

你写的strncpy(*filteredNames, *names, sizeof(a)/sizeof(char)-values);完全误解了strncpy的用途:

  • strncpy是用来拷贝单个字符串的,而*filteredNames是filteredNames数组的第一个指针元素,*names是names数组第一个字符串的首地址,用它来拷贝整个指针数组的内容完全不匹配场景。
  • 代码里的sizeof(a)是未定义变量,属于笔误;就算改成正确数组,sizeof的计算逻辑也不对——你要拷贝的是指针数组的元素,不是字符串的字节数。
  • 这种用法会导致内存越界或访问非法地址,直接触发段错误。

二、memcpy用法的错误

test函数里的memcpy(names,filterednames,sizeof(filterednames));有三个核心问题:

  1. 参数顺序颠倒:memcpy的第一个参数是目标地址,第二个是源地址,你想把筛选后的内容存入filterednames的话,应该是memcpy(filterednames, names, ...),反过来写会把filterednames的内容覆盖到names,而且names是const数组,不能被修改。
  2. sizeof计算错误:在函数参数中,char**& filterednames是指针引用,sizeof(filterednames)得到的是指针本身的大小(比如64位系统是8字节),不是你实际要拷贝的数组元素总字节数。必须手动传入数组的元素个数,才能计算出正确的拷贝长度。
  3. 类型不匹配:names是const char*类型的数组,而filterednames是char**,直接memcpy会丢失const属性,可能导致未定义行为。

三、正确的实现方式

场景1:和循环等价的浅拷贝(指针赋值,不拷贝字符串内容)

如果只是要和你之前的循环效果一致(浅拷贝,filteredNames的指针直接指向names里的字符串),用memcpy时需要明确元素个数:

// 假设已计算好要拷贝的元素个数count = randomLength - values
const char* names[randomLength] = {"test1","test2","test3"...};
const char* filteredNames[randomLength-values]; // 建议用const char*保持类型匹配

// 正确的memcpy写法:拷贝count个指针,每个指针大小为sizeof(const char*)
memcpy(filteredNames, names, count * sizeof(const char*));

场景2:test函数里的正确实现

如果要在函数内完成拷贝,必须传入要拷贝的元素个数,同时注意const类型匹配:

void test(const char**& filterednames, const char** names, size_t count)
{
    // 确保filterednames已分配足够内存(比如函数外已定义数组,或动态分配)
    memcpy(filterednames, names, count * sizeof(const char*));
}

// 调用示例
const char* names[5] = {"test1","test2","test3","test4","test5"};
size_t count = 3; // 筛选后保留3个元素
const char* filteredNames[3];
test(filteredNames, names, count);

注意:如果需要深拷贝(复制字符串内容,而非指针)

如果你需要为每个字符串分配新内存(不共享原字符串地址),不能直接memcpy指针,需要循环分配内存并拷贝字符串:

// 动态分配指针数组
char** filteredNames = malloc(count * sizeof(char*));
for (int i = 0; i < count; i++) {
    // 为每个字符串分配内存(+1是为了存储字符串结束符'\0')
    filteredNames[i] = malloc(strlen(names[i]) + 1);
    strcpy(filteredNames[i], names[i]);
}

// 使用完后记得释放内存
for (int i = 0; i < count; i++) {
    free(filteredNames[i]);
}
free(filteredNames);

内容的提问来源于stack exchange,提问作者Venkat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 13:20:27