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

使用memcpy移动结构体数组内容结果不符合预期该如何解决?

错误原因

  • 拷贝长度设置错误:原代码传入4 * sizeof(text_i)作为拷贝长度,会将从textlist[0]开始的4个元素全部拷贝到textlist[1]起始的位置,直接覆盖下标1到4的全部内容,不符合你不改动下标3、4的需求。
  • 内存重叠场景误用memcpy:源地址&textlist[0]和目标地址&textlist[1]对应的内存区域重叠,memcpy对重叠内存的操作行为是未定义的。主流实现会从低地址向高地址逐字节拷贝,第一次拷贝就会覆盖textlist[1]的原内容world ..,后续拷贝读取的源内容已经是被修改后的内容,最终导致所有被覆盖的位置都变成hello ..。

修改方案

将原memcpy调用替换为支持重叠内存安全拷贝的memmove,同时把拷贝长度调整为2个结构体元素的大小即可,刚好把原下标0、1的内容拷贝到下标1、2的位置,不会修改下标3、4的内容。

修改后的完整代码如下:

#include <stdio.h>
#include <string.h>
typedef struct {
      char texts[1024];
}text_i;
text_i textlist[5];
int main()
{
int ind;
strcpy( textlist[0].texts, "hello .."); 
strcpy( textlist[1].texts, "world .."); 
printf("texts before memcpy\n");
for (ind = 0; ind < 5 ; ind++)
        printf("texts ind(%d) is %s \n", ind, textlist[ind].texts);
// 替换为memmove,长度改为2个元素大小
memmove( &textlist[1], &textlist[0], 2 * sizeof(text_i));
printf("texts after memcpy\n");
for (ind = 0; ind < 5 ; ind++)
        printf("texts ind(%d) is %s \n", ind, textlist[ind].texts);
return 0;
}

可选替代方案

如果不想调用内存拷贝库函数,也可以手动从后往前赋值避免覆盖需要用到的源内容,效果完全一致:

// 先拷贝靠后的元素,避免提前覆盖源内容
textlist[2] = textlist[1];
textlist[1] = textlist[0];

运行后输出完全符合你的预期:

texts before memcpy
texts ind(0) is hello .. 
texts ind(1) is world .. 
texts ind(2) is  
texts ind(3) is  
texts ind(4) is  
texts after memcpy
texts ind(0) is hello .. 
texts ind(1) is hello .. 
texts ind(2) is world .. 
texts ind(3) is  
texts ind(4) is  

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 17:09:00