realloc():下一个大小无效(核心已转储)
realloc(): invalid next size (core dumped)
我有一个简单的函数,每次我想添加一个字符时都会重新分配缓冲区,直到我第 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]='[=10=]';
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] = '[=10=]';
return data;
}
}
和错误:
*** Error in `./bootstrap': realloc(): invalid next size: 0x0000000000b9f2a0 ***
Aborted (core dumped)
主要错误最有可能在这里:
data[strlen(data)] = c;
data[strlen(data)+1] = '[=10=]';
您首先用该字符覆盖空终止符。然后您尝试获取 不再具有空终止符 的字符串的长度,这意味着您将 运行 超过分配的内存,这意味着未定义的行为。您的分配将导致任何大小。然后你继续。
之前没有发生的原因很可能是因为分配的内存恰好在某个时候有一个空并且它保持在合理的范围内。但不是永远。
最好的方法是跟踪大小,不要每次都使用昂贵的 strlen()
,但如果你真的 must/want,请先将值存储在变量中。
size_t pos = strlen(data);
data[pos] = c;
data[pos+1] = '[=11=]';
甚至调换它们:
data[strlen(data)+1] = '[=12=]';
data[strlen(data)] = c;
您还可以重新分配完全相同的内存量,因为 strlen()+1
是从开头分配的 2 个字节(字符串 + 空终止符)。应该是 strlen()+2
.
另外,作为一个风格问题,sizeof(char)
根据定义是 1,因此您不需要使用它,除非您觉得它可以增加清晰度。
考虑一下它的第一次生长。
原来的分配是2个字符,很好,适合第一个payload字符和终止符。所以字符串的长度是1
,但是分配的长度是2
.
然后第一次增长计算出新的大小strlen(data) + 1
,我们知道字符串长度是1
所以就是2
。然后它在该位置使用 三个 字节...... Boom!
以此类推
您确实应该考虑一种表示形式,它为您提供字符串长度 和 分配的长度,并且应将它们分开。减少 strlen()
s。
我有一个简单的函数,每次我想添加一个字符时都会重新分配缓冲区,直到我第 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]='[=10=]';
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] = '[=10=]';
return data;
}
}
和错误:
*** Error in `./bootstrap': realloc(): invalid next size: 0x0000000000b9f2a0 ***
Aborted (core dumped)
主要错误最有可能在这里:
data[strlen(data)] = c;
data[strlen(data)+1] = '[=10=]';
您首先用该字符覆盖空终止符。然后您尝试获取 不再具有空终止符 的字符串的长度,这意味着您将 运行 超过分配的内存,这意味着未定义的行为。您的分配将导致任何大小。然后你继续。
之前没有发生的原因很可能是因为分配的内存恰好在某个时候有一个空并且它保持在合理的范围内。但不是永远。
最好的方法是跟踪大小,不要每次都使用昂贵的 strlen()
,但如果你真的 must/want,请先将值存储在变量中。
size_t pos = strlen(data);
data[pos] = c;
data[pos+1] = '[=11=]';
甚至调换它们:
data[strlen(data)+1] = '[=12=]';
data[strlen(data)] = c;
您还可以重新分配完全相同的内存量,因为 strlen()+1
是从开头分配的 2 个字节(字符串 + 空终止符)。应该是 strlen()+2
.
另外,作为一个风格问题,sizeof(char)
根据定义是 1,因此您不需要使用它,除非您觉得它可以增加清晰度。
考虑一下它的第一次生长。
原来的分配是2个字符,很好,适合第一个payload字符和终止符。所以字符串的长度是1
,但是分配的长度是2
.
然后第一次增长计算出新的大小strlen(data) + 1
,我们知道字符串长度是1
所以就是2
。然后它在该位置使用 三个 字节...... Boom!
以此类推
您确实应该考虑一种表示形式,它为您提供字符串长度 和 分配的长度,并且应将它们分开。减少 strlen()
s。