WSL环境下GCC编译C代码时strcpy执行结果不符合预期
问题:WSL下GCC使用strcpy处理重叠字符串出现异常
在WSL环境使用GCC编译C代码时,尝试通过strcpy删除字符串前导空格,出现不符合预期的结果:
- 原字符串为
{' ','e','h','c','o' ,'\0'},用指针temp指向字符'e'后调用strcpy(a, temp),得到结果为ecoo,而非预期的echo - 调试确认
temp指向的内容确实是echo,且代码在Windows的Visual Studio和VSCode中运行正常 - 测试不同长度字符串时,发现长度为3、7时代码可正常运行
原代码
#include <stdio.h> #include <unistd.h> #include <string.h> int main(){ char a[256]; a[0] = ' '; a[1] = 'e'; a[2] = 'h'; a[3] = 'c'; a[4] = 'o'; a[5] = '\0'; char* temp = a; temp ++ ; printf("%s\n",temp); strcpy(a,temp); printf("%s\n",a); }
原因分析
strcpy不支持内存重叠的场景。根据C语言标准,当源字符串和目标字符串的内存区域重叠时,strcpy的行为是未定义的。Windows平台的编译器(如MSVC)可能对这种情况做了兼容处理,而WSL中的GCC严格遵循标准,未定义行为会导致随机的异常结果(比如部分字符被提前覆盖),不同长度字符串表现不同也是这种随机性的体现。
解决方案
使用memmove替代strcpy,memmove专门设计用于处理内存重叠的复制场景,它会先将源数据临时存储,再写入目标地址,避免覆盖问题。修改后的代码如下:
#include <stdio.h> #include <string.h> int main(){ char a[256]; a[0] = ' '; a[1] = 'e'; a[2] = 'h'; a[3] = 'c'; a[4] = 'o'; a[5] = '\0'; char* temp = a + 1; printf("%s\n", temp); memmove(a, temp, strlen(temp) + 1); // +1 是为了复制字符串结束符 '\0' printf("%s\n", a); }
内容的提问来源于stack exchange,提问作者nanxiang xia
相关产品推荐
相关产品推荐

