realloc(): 无效的下一个大小(核心转储)

noc*_*rne 0 c realloc

我有一个简单的函数,每次我想添加一个字符时都会重新分配缓冲区,它一直工作到我想第 24 次重新分配。然后 realloc(): invalid next size 出现。这是代码:

char * addDataChunk(char * data,char c)
{
    char * p;
    if(data==NULL)
    {
        data=(char*)malloc(sizeof(char)*2);
        data[0]=c;
        data[1]='\0';
        return data;
    }
    else
    {
        if(p = (char*)realloc(data,((strlen(data)+1)*sizeof(char))))
        {
            data = p;
        }
        else
        {
            printf("realloc error\n");
        }
        data[strlen(data)] = c;
        data[strlen(data)+1] = '\0';
        return data;
    }
}
Run Code Online (Sandbox Code Playgroud)

和错误:

*** Error in `./bootstrap': realloc(): invalid next size:     0x0000000000b9f2a0 ***
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

Sam*_*nen 7

主要错误很可能在这里:

data[strlen(data)] = c;
data[strlen(data)+1] = '\0';
Run Code Online (Sandbox Code Playgroud)

首先用字符覆盖空终止符。然后您尝试获取不再具有空终止符的字符串的长度,这意味着您将运行分配的内存,这意味着未定义的行为。您的分配将导致任何大小。然后你继续。

之前没有发生的原因很可能是因为分配的内存在某个时候碰巧有一个空值,并且它保持在合理的边界内。但不是永远。

最好的方法是跟踪大小而不是strlen()每次都使用昂贵的,但如果你真的必须/想要,首先将值存储在变量中。

size_t pos = strlen(data);
data[pos] = c;
data[pos+1] = '\0';
Run Code Online (Sandbox Code Playgroud)

甚至切换它们:

data[strlen(data)+1] = '\0';
data[strlen(data)] = c;
Run Code Online (Sandbox Code Playgroud)

此外,您将重新分配完全相同的内存量,因为strlen()+1是从头开始分配的 2 个字节(字符串 + 空终止符)。应该是strlen()+2。

同样作为样式问题,sizeof(char)根据定义 1,除非您觉得它增加了一些清晰度,否则您不需要使用它。