malloc上的分段错误

时间:2013-04-08 14:35:44

标签: c

运行此函数很多次(不确定确切的次数)后,它会在简单的内存分配上出错。为什么突然发生这种情况?我在GDB中注意到了一些奇怪的东西。在调用它的函数中,通常wrd有6位长的十六进制值(例如wrd = 0x605140),但是在它崩溃的调用中,十六进制值只有两位数长。 (WRD = 0×21)。我还检查了wrd->长度,它是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;

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

1 个答案:

答案 0 :(得分: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是一个本地字符数组,那么一旦它超出范围,wrd->letters就会变成一个悬空指针,它会被其他数据覆盖,之后修改它会导致内存损坏。

可能的修复(取决于代码的其余部分)是使用strdup

wrd->letters = strdup(input);

请记住它现在是从堆中分配的,所以一旦完成,你必须记得做

free(wrd->letters);

关于wrd为0x21,表示内存损坏,或者您实际上有两个单独的wrd变量,并且其中一个未初始化。

例如,可能wrd是函数参数struct word *wrd,在这种情况下,您只修改函数中的本地值,它不会传递回调用者。要修改调用者的指针,您需要指向指针:struct word **wrd,然后执行(*wrd) = malloc...(*wrd)->letters...等。