C 中的 realloc() 问题。总是挂起,但编译正常
我在使用一个旨在成为字符串缓冲区的程序时遇到了一些麻烦,特别是此函数旨在使用字符串 cstr 重置缓冲区。如果 cstr 为 null,则需要将内容重置为空字符“\0”。它总是挂在第二组 realloc 上,它正在调整 buf->contents 的大小,我不知道为什么会这样。任何帮助都会很棒。
结构:
typedef struct strbuf {
char *contents;
size_t length;
} StringBuffer;
它是从
strbuf_reset(sb, NULL)
这里调用的,这是有问题的 strbuf_reset 函数。
StringBuffer *strbuf_reset(StringBuffer *buf, const char *cstr)
{
if(buf == NULL)
return NULL;
StringBuffer *tempBuf = NULL ;
if(cstr == NULL)
tempBuf = (StringBuffer*)realloc(buf,sizeof(StringBuffer) + sizeof(char));
else
tempBuf = (StringBuffer*)realloc(buf,sizeof(buf) + strlen(cstr)*sizeof(char));
if(tempBuf == NULL)
return NULL;
if(cstr == NULL)
tempBuf->contents = (char*)realloc(buf->contents,sizeof(char));
else
tempBuf->contents = (char*)realloc(buf->contents,(sizeof(buf->contents) + strlen(cstr)*sizeof(char) + 1));
if(tempBuf->contents == NULL){
free(tempBuf);
return NULL;
}
buf = tempBuf;
if(cstr == NULL)
buf->contents = '\0';
else
strcat(buf->contents,cstr);
buf->length = strlen(buf->contents);
return buf;
}
我认为建议的改变......
StringBuffer *strbuf_reset(StringBuffer *buf, const char *cstr)
{
if(buf == NULL)
return NULL;
StringBuffer *tempBuf = NULL ;
if(cstr == NULL)
tempBuf = (StringBuffer*)realloc(buf,sizeof(StringBuffer) + sizeof(char) + 10);
else
tempBuf = (StringBuffer*)realloc(buf,sizeof(buf) + strlen(cstr)*sizeof(char)+ 1);
if(tempBuf != NULL)
buf = tempBuf;
else
return NULL;
if(cstr == NULL)
tempBuf->contents = (StringBuffer*)realloc(buf->contents,sizeof(StringBuffer) + sizeof(char) + 10);
else
tempBuf->contents = (StringBuffer*)realloc(buf->contents,sizeof(buf) + strlen(cstr)*sizeof(char)+ 1);
if(tempBuf != NULL)
buf->contents = tempBuf->contents;
else
return NULL;
if(cstr == NULL)
buf->contents = '\0';
else
strcat(buf->contents,cstr);
buf->length = strlen(buf->contents);
return buf;
}
I'm having some trouble with a program that is intended to be a String buffer, specifically this function is intended to reset the buffer with the string cstr. If cstr is null then the content needs to be reset to an empty char '\0'. It always hangs at the second set of realloc where it's resizing buf->contents I have no clue why that is. Any help would be awesome.
The struct:
typedef struct strbuf {
char *contents;
size_t length;
} StringBuffer;
It is called from
strbuf_reset(sb, NULL)
Here is the strbuf_reset function that is having the problem.
StringBuffer *strbuf_reset(StringBuffer *buf, const char *cstr)
{
if(buf == NULL)
return NULL;
StringBuffer *tempBuf = NULL ;
if(cstr == NULL)
tempBuf = (StringBuffer*)realloc(buf,sizeof(StringBuffer) + sizeof(char));
else
tempBuf = (StringBuffer*)realloc(buf,sizeof(buf) + strlen(cstr)*sizeof(char));
if(tempBuf == NULL)
return NULL;
if(cstr == NULL)
tempBuf->contents = (char*)realloc(buf->contents,sizeof(char));
else
tempBuf->contents = (char*)realloc(buf->contents,(sizeof(buf->contents) + strlen(cstr)*sizeof(char) + 1));
if(tempBuf->contents == NULL){
free(tempBuf);
return NULL;
}
buf = tempBuf;
if(cstr == NULL)
buf->contents = '\0';
else
strcat(buf->contents,cstr);
buf->length = strlen(buf->contents);
return buf;
}
With what I believe to be the suggested changes...
StringBuffer *strbuf_reset(StringBuffer *buf, const char *cstr)
{
if(buf == NULL)
return NULL;
StringBuffer *tempBuf = NULL ;
if(cstr == NULL)
tempBuf = (StringBuffer*)realloc(buf,sizeof(StringBuffer) + sizeof(char) + 10);
else
tempBuf = (StringBuffer*)realloc(buf,sizeof(buf) + strlen(cstr)*sizeof(char)+ 1);
if(tempBuf != NULL)
buf = tempBuf;
else
return NULL;
if(cstr == NULL)
tempBuf->contents = (StringBuffer*)realloc(buf->contents,sizeof(StringBuffer) + sizeof(char) + 10);
else
tempBuf->contents = (StringBuffer*)realloc(buf->contents,sizeof(buf) + strlen(cstr)*sizeof(char)+ 1);
if(tempBuf != NULL)
buf->contents = tempBuf->contents;
else
return NULL;
if(cstr == NULL)
buf->contents = '\0';
else
strcat(buf->contents,cstr);
buf->length = strlen(buf->contents);
return buf;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您似乎不明白
realloc
的作用。您应该考虑它的方式(至少就放大而言)是,它分配一个新缓冲区,将旧数据复制到其中,然后释放旧缓冲区< /em>.
那么旧指针无效,如果稍后尝试再次使用它时发生崩溃,也不足为奇。
您应该立即将返回值分配回旧指针,因此它仍然指向有效数据。
You don't seem to understand what
realloc
does.The way you should be thinking about it (at least as far as enlarging goes), is that it allocates a new buffer, copies the old data into it, and then frees the old buffer.
The old pointer is then invalid and it should not be suprising if you get crashes when you try and use it again later.
You should be assigning the returned value back to the old pointer immediately, so it still points at valid data.
由于您要覆盖 StringBuffer 的内容,因此使用 realloc 没有任何意义。它不会为您节省任何内存分配,而是会复制您打算覆盖的旧数据。使用普通的 malloc 和 free。
使用原始结构
strbuf_reset 将 buf 设置为 cstr。成功时返回 buf,失败时返回 NULL。
Since you are going to overwrite StringBuffer's contents, using realloc makes no sense. It will not save you any memory allocation but instead will copy old data you intent to overwrite anyway. Use normal malloc and free.
With your original structure
strbuf_reset sets buf to cstr. On success returns buf, on failure NULL.
您正在为 StringBuffer 中的字符串分配额外的空间。我只是假设 buf->contents 应该指向额外分配的空间。如果这不是真的,那么为什么要在 StringBuffer 中分配额外的空间呢?
如果 buf->contents 已经指向为 StringBuffer 分配的内存,尝试重新分配它将使内存系统陷入崩溃/挂起/损坏堆的情况,因为您将重新分配一个从未分配的指针。
我认为结构应该如下所示,而不是尝试重新分配 buf->contents:
然后,您只需将字符串复制到那里,而不是重新分配 buf->contents,并且 StringBuffer 的重新分配会处理所有内存。
You are allocating extra space for the string in the StringBuffer. I just assumed buf->contents is supposed to point into that extra allocated space. If this is not true then why is the extra space allocated in the StringBuffer?
If buf->contents already points into memory that was allocated for StringBuffer, attempting to realloc it will throw the memory system into a crash/hang/corrupt heap situation, because you would be realloc'ing a pointer that was never allocated.
Instead of attempting to realloc buf->contents, I think the structure should look like:
Then instead of reallocing buf->contents you just copy the string into there and the realloc for StringBuffer takes care of all the memory.