我正在为一个班级编写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”)被正确捕获。
有谁知道这里发生了什么?
答案 0 :(得分: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,因此您无需乘以它。
答案 1 :(得分:2)
cond被分配一个字节。 strcpy正在将至少两个字节复制到该分配。也就是说,您在分配中写入的字节数多于可用空间。
修复它以使用char *cond = malloc (1000);
代替你所拥有的一种方法。
答案 2 :(得分:1)
您只为1个字符分配了内存,但是您尝试存储至少6个字符(您需要空间来终止\ 0)。解决这个问题的快捷方法就是说
char cond [128]
而不是malloc。