3

我正在为一个类编写 C 代码。这个类要求我们的代码在学校服务器上编译运行,这是一台 sparc solaris 机器。我正在运行 Linux x64。

我要解析这一行(这不是实际代码,而是输入到我的程序中):

while ( cond1 ){ 

我需要将“while”和“cond1”捕获到单独的字符串中。我一直strtok()用来做这个。在 Linux 中,以下行:

char *cond = NULL;
cond = (char *)malloc(sizeof(char));
memset(cond, 0, sizeof(char));
strcpy(cond, strtok(NULL, ": \t\(){")); //already got the "while" out of the line

将正确捕获字符串“cond1”。但是,在 Solaris 机器上运行它会得到字符串“cone1”。

请注意,在我的程序中的许多其他情况下,字符串被正确复制。(例如,“while”)被正确捕获。

有谁知道这里发生了什么?

4

3 回答 3

11

该行:

cond = (char *)malloc(sizeof(char));

仅分配一个char用于存储,然后您将在其中复制多个 - 至少strcpy需要放置空终止符,但在您的情况下,您的结果strtok也是如此。

它可能在不同系统上工作的原因是,无论您要求什么实际值,某些实现malloc都会以特定分辨率(例如,16 字节的倍数)分配,因此您可能在末尾有一些可用空间你的缓冲区。但是您正在尝试的仍然是非常未定义的行为。

未定义的行为有时可能会起作用,这一事实绝不会免除您避免此类行为的责任。

分配足够的空间来存储你的结果,strtok你应该没问题。

最安全的方法是动态分配空间,使其至少与您传递给的字符串一样大strtok。这样就不会有溢出的可能性(除了奇怪的边缘情况,其他线程可能会修改你背后的数据,但如果是这样的话,strtok无论如何都是一个非常糟糕的选择)。

类似于(如果instr是您的原始输入字符串):

cond = (char*)malloc(strlen(instr)+1);

这保证了从中提取的任何令牌instr都适合cond.

顺便说一句,sizeof(char)根据定义,它始终为 1,因此您无需乘以它。

于 2010-04-16T05:29:14.917 回答
2

cond 被分配一个字节。strcpy 正在将至少两个字节复制到该分配中。也就是说,您在分配中写入的字节数超过了空间。

修复它的一种方法是使用它char *cond = malloc (1000);而不是你所拥有的。

于 2010-04-16T05:31:14.897 回答
1

您只为 1 个字符分配了内存,但您尝试存储至少 6 个字符(您需要用于终止 \0 的空间)。解决这个问题的快速而肮脏的方法就是说

字符条件[128]

而不是malloc。

于 2010-04-16T05:31:01.370 回答