实现memmove类似功能时遇编译错误,求问题分析与解决
ft_memmove实现问题排查与解答
编译错误原因
你遇到的error: lvalue required as increment operand错误和const数组无关,问题出在p++操作上:p是栈上变长数组的数组名,它本质是不可修改的左值(只读的指针常量),不能对它执行自增、自减这类修改操作。数组名在多数场景下会退化为指向数组首元素的指针,但它本身不是可修改的变量,因此不能用p++遍历数组。
memmove工作原理的确认
你对memmove的理解是正确的:man手册明确说明,memmove会先将源数据复制到一个不与目标地址重叠的临时区域,再将临时区域的数据复制到目标地址,以此避免源数据在复制过程中被覆盖(当源和目标地址重叠时)。
是否需要使用malloc?
当前用的栈上变长数组unsigned char p[n];在小数据量测试时没问题,但如果n的值很大,栈空间会被耗尽,导致栈溢出崩溃。所以更健壮的实现应该用malloc动态分配临时内存,用完后记得用free释放,避免内存泄漏。如果只是学习阶段做小范围测试,用变长数组也可以,但要注意数组的正确使用方式。
修正后的代码示例
方案1:用临时指针遍历栈上数组
把数组名赋值给一个可修改的指针变量,通过操作这个指针来遍历数组:
void *ft_memmove(void *dest, const void *src, size_t n) { unsigned char p[n]; unsigned char *temp_p; unsigned char *p2; const unsigned char *p3; size_t i; p2 = (unsigned char *)dest; p3 = (const unsigned char *)src; temp_p = p; i = 0; // 先把源数据复制到临时数组 while (i < n) { *(temp_p++) = *(p3++); i++; } // 重置临时指针到数组开头 temp_p = p; // 把临时数组的数据复制到目标地址 while (n--) { *(p2++) = *(temp_p++); } return (dest); }
方案2:用malloc动态分配临时内存(更健壮)
避免栈溢出问题,同时处理边界情况:
void *ft_memmove(void *dest, const void *src, size_t n) { unsigned char *temp; unsigned char *p2; const unsigned char *p3; size_t i; // 边界情况:无需复制或源目标地址相同 if (n == 0 || dest == src) return (dest); // 动态分配临时内存 temp = (unsigned char *)malloc(n); if (!temp) return (NULL); // 内存分配失败返回NULL p2 = (unsigned char *)dest; p3 = (const unsigned char *)src; // 复制源数据到临时内存 for (i = 0; i < n; i++) temp[i] = p3[i]; // 复制临时内存数据到目标地址 for (i = 0; i < n; i++) p2[i] = temp[i]; // 释放临时内存 free(temp); return (dest); }
内容的提问来源于stack exchange,提问作者Sami Walid
相关产品推荐
相关产品推荐

