我有一个简单的函数,每次我想添加一个char时重新分配缓冲区,它一直工作,直到我想第24次重新分配。然后realloc():出现无效的下一个大小。这是代码:
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;
}
}
和错误:
*** Error in `./bootstrap': realloc(): invalid next size: 0x0000000000b9f2a0 ***
Aborted (core dumped)
答案 0 :(得分:4)
主要错误很可能在这里:
strlen()
首先用字符覆盖null终止符。然后,您尝试获取不再具有空终止符的字符串的长度,这意味着您将在已分配的内存上运行,这意味着未定义的行为。您的分配将产生任何大小。然后你继续。
之前没有发生过的原因很可能是因为分配的内存在某个时刻碰巧出现空值并且它保持在合理的边界内。但不是永远。
最好的方法是跟踪大小而不是每次都使用昂贵的size_t pos = strlen(data);
data[pos] = c;
data[pos+1] = '\0';
,但如果你真的必须/想要,首先将值存储在变量中。
data[strlen(data)+1] = '\0';
data[strlen(data)] = c;
甚至可以切换它们:
strlen()+1
此外,您将重新分配完全相同的内存量,因为strlen()+2
是从头开始分配的2个字节(字符串+空终止符)。它应该是sizeof(char)
。
同样作为一个样式问题,message.getRecipients(Message.RecipientType.TO)
根据定义1,因此您不需要使用它,除非您觉得它增加了清晰度。
答案 1 :(得分:1)
考虑第一次成长。
原始分配是2个字符,这很好,它适合第一个有效负载字符和终结符。所以字符串的长度为1
,但分配的长度为2
。
然后第一次增长计算strlen(data) + 1
的新大小,我们知道字符串长度为1
,因此2
。strlen()
。然后它在该位置使用三个字节...... Boom!
等等。
你真的应该考虑一个代表,它给你字符串长度和分配的长度,这些应该保持分开。减少appannie.py
s。