0

在多次运行此函数(不确定具体多少次)后,它会在简单的内存分配上出现故障。为什么会突然出现这种情况?我确实注意到 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;

如果我遇到溢出,我该如何解决?

4

1 回答 1

0

貌似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...

于 2013-04-08T14:44:13.703 回答