strtok()行为在编译器之间是不同的

时间:2015-02-12 02:00:04

标签: c strtok

我编写了一个程序,根据这种格式解析字符串:

somethingsomething:number:

在我的电脑上,这个程序完美无瑕。 但是,一旦我上传了代码并将其编译在学校的计算机上,strtok()就会有不同的行为。

例如,使用此字符串:p2test/f4.txt:1:,在我的计算机上,第一个标记为p2test/f4.txt。但是,在学校的计算机上,令牌最终为p2test/f4.t

以下是代码段:

            char *token;
            char delim[1] = ":";

            if ((token = strtok(tmp_string, delim)) != NULL) {
                ...
            }

此处tmp_stringp2test/f4.txt:1:

这是我的电脑的编译器版本:gcc版本4.9.1(Ubuntu 4.9.1-16ubuntu6)

这是我学校的编译器版本:gcc版本4.8.1 20130909 [gcc-4_8-branch revision 202388](SUSE Linux)

2 个答案:

答案 0 :(得分:1)

除了评论中提到的几个问题,看起来代码存在更大的问题。根据手册页中的getline()函数的描述:

  If  *lineptr  is set to NULL and *n is set 0 before the call, then get‐
  line() will allocate a buffer for storing the line.  This buffer should
  be freed by the user program even if getline() failed.

  Alternatively, before calling getline(), *lineptr can contain a pointer
  to a malloc(3)-allocated buffer *n bytes in size.  If the buffer is not
  large  enough  to  hold the line, getline() resizes it with realloc(3),
  updating *lineptr and *n as necessary.

你没有初始化tmp_string,因此它的值是一些指向某个随机地址的未初始化的垃圾,并且发生了上述getline()的第二种替代行为。

这看起来像我未定义的行为。

P.S。您确实将长度值初始化为0字节,根据getline()的手册页,它会调用realloc。所以,它看起来你的代码最终间接地将垃圾指针传递给realloc。

答案 1 :(得分:1)

另一个问题是你在这里有一个记忆覆盖:

char delim[1] = ":";

字符串中有两个字符,而不是1.执行此操作更安全:

char delim[] = ":";