在多次(不确定确切次数)运行此功能后,它会在简单的内存分配上隔离错误。为什么会突然发生这种情况?我确实注意到GDB中有些奇怪的地方。在调用它的函数中,wrd通常有6位长的十六进制值(例如,wrd = 0x605140),但是在崩溃的调用中,十六进制值只有两位数字。 (wrd = 0x21)。我还检查了wrd-> length,它是3。
它崩溃的那条线是...
char *word_temp = malloc(wrd->length * sizeof(char));
编辑:
这是创建wrd的代码...
while(fgets(input, 100, src) != 0)
{
int i = 0;
while(input[i] != '\0')
{
i++;
}
struct word *wrd = malloc(sizeof(struct word));
wrd->letters = input;
wrd->length = i;
如果出现溢出,该如何解决?
最佳答案
看起来wrd->length
不包含终止的'\0'
。
修复1,像这样分配word_temp
:
char *word_temp = malloc( wrd->length + 1 );
修订2,通过修改长度计数循环来包含'\ 0':
int i = 0;
while(input[i++] != '\0') {}
与问题中的代码相比,这将使
i
增加多一倍的时间,如果您认为input
为空的情况很容易看出。请注意,您需要执行修复1或修复2,而不是两者。选择适合您其余代码的代码。
您可能对此行有第二个问题:
wrd->letters = input;
它不复制输入,而是复制指针。如果更改
input
的内容,则wrd->letters
的内容也会更改,因为它们指向相同的存储位置。同样,如果input
是本地char数组,则一旦它超出范围,wrd->letters
就会成为一个悬空指针,它将被其他数据覆盖,然后对其进行修改将导致内存损坏。可能的解决方法(取决于代码的其余部分)是使用
strdup
:wrd->letters = strdup(input);
请记住,它现在是从堆中分配的,因此完成后,您必须记住
free(wrd->letters);
大约
wrd
为0x21,表示内存损坏,或者您实际上有两个单独的wrd
变量,并且其中一个未初始化。例如,
wrd
可能是函数参数struct word *wrd
,在这种情况下,您仅修改函数中的本地值,不会将其传递回调用方。要修改调用者的指针,您需要具有指向指针的指针:struct word **wrd
,然后执行(*wrd) = malloc...
和(*wrd)->letters...
等。