strstr:使用不同版本的 gcc 时行为不同
我正在将一个适用于 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 提供正确的输出,并且最好解释一下这里发生的情况。
提前致谢!
I'm porting a program that works with Ubuntu 8.04 (gcc version 4.2.4) to 10.04 (gcc version 4.4.3). I have the following code:
#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;
}
The result should be /abcd
, which it is with gcc 4.2.4. With 4.4.3, the output is /accd
.
Can you suggest me a code change that will give the correct output using both versions of gcc, and preferrably explain what is going on here.
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你只是很幸运。
来自
strcpy
文档:在您的情况下,字符串重叠,您的程序将调用未定义的行为。
它曾经有效但不再有效的一个可能原因是
strcpy
可以由 GCC 实现为内置函数,如memmove
(即在这种情况下安全),但是这个出于性能原因更改为非安全版本。 (这纯粹是猜测。)要修复它,请使用
memmove
而不是strcpy
,类似于:这不是非常高效,但它可以移植 -
memmove
必须处理重叠内存地区。You've just been lucky.
From the
strcpy
documentation:The strings overlap in your case, your program invokes undefined behavior.
A possible reason why it used to work but no longer does is that
strcpy
could have been implemented as a builtin by GCC likememmove
(i.e. safe in this situation), but this changed to a non-safe version for performance reasons. (This is pure speculation.)To fix it, use
memmove
rather thanstrcpy
, with something like:That's not terribly efficient, but it will work portably -
memmove
has to handle overlapping memory areas.