Strcpy()会损坏Solaris中复制的字符串,但不会损坏Linux

时间:2021-11-01 05:57:49

I'm writing a C code for a class. This class requires that our code compile and run on the school server, which is a sparc solaris machine. I'm running Linux x64.

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

I have this line to parse (THIS IS NOT ACTUAL CODE BUT IS INPUT TO MY PROGRAM):

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

while ( cond1 ){ 

I need to capture the "while" and the "cond1" into separate strings. I've been using strtok() to do this. In Linux, the following lines:

我需要将“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

will correctly capture the string "cond1".Running this on the solaris machine, however, gives me the string "cone1".

将正确捕获字符串“cond1”。然而,在solaris计算机上运行这个函数,会得到字符串“cone1”。

Note that in plenty of other cases within my program, strings are being copied correctly. (For instance, the "while") was captured correctly.

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

Does anyone know what is going on here?

有人知道这是怎么回事吗?

3 个解决方案

#1


11  

The line:

线:

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

allocates exactly one char for storage, into which you are then copying more than one - strcpy needs to put, at a bare minimum, the null terminator but, in your case, also the results of your strtok as well.

为存储分配一个确切的字符,然后将多个字符复制到其中——strcpy需要将空终止符(最低限度)放入,但是在您的例子中,还包括strtok的结果。

The reason it may work on a different system is that some implementations of malloc will allocate at a certain resolution (e.g., a multiple of 16 bytes) no matter what actual value you ask for, so you may have some free space there at the end of your buffer. But what you're attempting is still very much undefined behaviour.

它可以在不同的系统上工作的原因是malloc的某些实现将以一定的分辨率(例如,16字节的倍数)进行分配,无论您要求的实际值是多少,因此在您的缓冲区末尾可能有一些空闲空间。但是你所尝试的仍然是非常不明确的行为。

The fact that the undefined behaviour may be to work sometimes in no way abrogates your responsibility to avoid such behaviour.

不明确的行为有时可能是为了工作,这一事实绝不能免除你避免这种行为的责任。

Allocate enough space for storing the results of your strtok and you should be okay.

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

The safest way to do this is to dynamically allocate the space so that it's at least as big as the string you're passing to strtok. That way there can be no possibility of overflow (other than weird edge cases where other threads may modify the data behind your back but, if that were the case, strtok would be a very bad choice anyway).

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

Something like (if instr is your original input string):

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

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

This guarantees that any token extracted from instr will fit within cond.

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

As an aside, sizeof(char) is always 1 by definition, so you don't need to multiply by it.

顺便说一句,sizeof(char)的定义总是1,所以不需要乘以它。

#2


2  

cond is being allocated one byte. strcpy is copying at least two bytes to that allocation. That is, you are writing more bytes into the allocation than there is room for.

cond被分配为一个字节。strcpy将至少两个字节复制到该分配中。也就是说,您在分配中写入的字节比空间要多。

One way to fix it to use char *cond = malloc (1000); instead of what you've got.

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

#3


1  

You only allocated memory for 1 character but you trying to store at least 6 characters (you need space for the terminating \0). The quick and dirty way to solve this is just say

您只为一个字符分配内存,但您试图存储至少6个字符(您需要空间来终止\0)。解决这个问题的简单方法是

char cond[128]

char气孔导度[128]

instead of malloc.

而不是malloc。

#1


11  

The line:

线:

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

allocates exactly one char for storage, into which you are then copying more than one - strcpy needs to put, at a bare minimum, the null terminator but, in your case, also the results of your strtok as well.

为存储分配一个确切的字符,然后将多个字符复制到其中——strcpy需要将空终止符(最低限度)放入,但是在您的例子中,还包括strtok的结果。

The reason it may work on a different system is that some implementations of malloc will allocate at a certain resolution (e.g., a multiple of 16 bytes) no matter what actual value you ask for, so you may have some free space there at the end of your buffer. But what you're attempting is still very much undefined behaviour.

它可以在不同的系统上工作的原因是malloc的某些实现将以一定的分辨率(例如,16字节的倍数)进行分配,无论您要求的实际值是多少,因此在您的缓冲区末尾可能有一些空闲空间。但是你所尝试的仍然是非常不明确的行为。

The fact that the undefined behaviour may be to work sometimes in no way abrogates your responsibility to avoid such behaviour.

不明确的行为有时可能是为了工作,这一事实绝不能免除你避免这种行为的责任。

Allocate enough space for storing the results of your strtok and you should be okay.

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

The safest way to do this is to dynamically allocate the space so that it's at least as big as the string you're passing to strtok. That way there can be no possibility of overflow (other than weird edge cases where other threads may modify the data behind your back but, if that were the case, strtok would be a very bad choice anyway).

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

Something like (if instr is your original input string):

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

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

This guarantees that any token extracted from instr will fit within cond.

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

As an aside, sizeof(char) is always 1 by definition, so you don't need to multiply by it.

顺便说一句,sizeof(char)的定义总是1,所以不需要乘以它。

#2


2  

cond is being allocated one byte. strcpy is copying at least two bytes to that allocation. That is, you are writing more bytes into the allocation than there is room for.

cond被分配为一个字节。strcpy将至少两个字节复制到该分配中。也就是说,您在分配中写入的字节比空间要多。

One way to fix it to use char *cond = malloc (1000); instead of what you've got.

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

#3


1  

You only allocated memory for 1 character but you trying to store at least 6 characters (you need space for the terminating \0). The quick and dirty way to solve this is just say

您只为一个字符分配内存,但您试图存储至少6个字符(您需要空间来终止\0)。解决这个问题的简单方法是

char cond[128]

char气孔导度[128]

instead of malloc.

而不是malloc。