c - strstr:使用不同版本的 gcc 时行为不同

标签 c gcc strstr

我正在将一个适用于 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/

相关文章:

c - time() 和 stime() 之间的区别

c - 使用gcc命令行从.c文件构建.so文件

c++ - 将两个 map 相加

c - 如何关闭来自 gcc 的错误浮点/长错误消息

c - 在 C 中查找子字符串在字符串中的位置

C 编程初学者(数组)

C、自由函数表现得很奇怪。为什么?

c - 我的 strstr 函数有效,但一个旨在测试它的程序说它不起作用

c - 以二进制格式写入文件时输出错误

php - 我想要一个不同的变量来存储通过 stristr 但不能包含除这 3 个不同的东西之外的任何东西