我正在将一个适用于 Ubuntu 8.04(gcc 版本 4.2.4)的程序移植到 10.04(gcc 版本 4.4.3)。我有以下代码:
#include <stdio.h>
#include <string.h>
int main(void) {
char p[100] = "////abcd";
char *t;
/* Remove duplicate slashes, saving only one of them */
while (t = strstr(p, "//"))
strcpy(t, t + 1);
printf("%s\n", p);
return 0;
}
结果应该是/abcd
,gcc 4.2.4 就是这样。对于 4.4.3,输出为 /accd
。
您能否建议我使用两个版本的 gcc 提供正确输出的代码更改,最好解释一下这里发生了什么。
提前致谢!
最佳答案
你真幸运。
来自strcpy
文档:
The strcpy() function shall copy the string pointed to by s2 (including the terminating null byte) into the array pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined.
在您的情况下字符串重叠,您的程序调用未定义的行为。
它过去可以工作但不再工作的一个可能原因是 strcpy
可以像 memmove
一样被 GCC 实现为内置函数(即在这种情况下是安全的) ,但出于性能原因,这已更改为非安全版本。 (这纯粹是猜测。)
要修复它,请使用 memmove
而不是 strcpy
,像这样:
while (t = strstr(p, "//")) {
memmove(t, t+1, strlen(t)); // strlen(t)'s bytes worth of data
// will cover the string bytes left
// and the \0 terminator
}
这不是非常有效,但它可以移植 - memmove
必须处理重叠的内存区域。
关于c - strstr:使用不同版本的 gcc 时行为不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7531068/