以下代码抛出错误:
mem(44582)malloc: *对象0x7f9f8a4000e0的错误:未释放指针被释放 * 在malloc_error_break中设置断点以进行调试 中止陷阱:6
我不确定发生了什么。我释放了一个显式malloc的内存区域,它是否与传入指向另一个方法的指针有关?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFERSIZE 10
void readstringbuffered(char *buffer);
int main(int argc, char const *argv[])
{
char *buffer = (char *)malloc(BUFFERSIZE);
readstringbuffered(buffer);
printf("%s",buffer);
free(buffer);
return EXIT_SUCCESS;
}
void readstringbuffered(char *buffer)
{
FILE *source;
source = fopen("hello.txt","r");
int current_size = BUFFERSIZE;
int len = 0;
int c;
while((c = fgetc(source)) != EOF)
{
if(len == current_size-1)
{
current_size *= 2;
char *temp = (char *)realloc(buffer,current_size);
if(!temp)
{
fprintf(stderr,"out of memory");
exit(1);
}
buffer = temp;
}
buffer[len] = c;
len++;
}
buffer[len] = 0;
}
答案 0 :(得分:8)
C是一种按值传递的语言。您在buffer
函数中对readstringbuffered()
所做的修改不会影响buffer
中main()
的值。如果realloc()
已执行,您已经释放buffer
知道的main
,当您返回时 - BAM - 双倍免费。
一种可能的解决方案是将指针传递给buffer
,而不是buffer
本身。将readstringbuffered()
的签名更改为:
void readstringbuffered(char **buffer)
然后在其中使用*buffer
。在呼叫站点,您可以使用readstringbuffered(&buffer)
传递必要的指针。
答案 1 :(得分:3)
realloc()可以释放先前分配的内存并在其他地方再次分配,这使得主缓冲区指针完全无效。您可以通过引用传递缓冲区并使readtringbuffered()相应地修改它,或者返回指向缓冲区而不是void的指针。
答案 2 :(得分:2)
main()
中的缓冲区指针不会根据readstringbuffered()
中的重新分配进行修改,您可以使用指向缓冲区指针的指针(pBuffer
)来回写缓冲区指针,像这样:
void readstringbuffered(char** pBuffer,size_t* pSize)
{
char* buffer = *pBuffer;
size_t size = MIN_SIZE;
char* newBufferPtr = (char*) realloc(buffer,size);
if(newBufferPtr)
{
buffer = newBufferPtr;
}
else
{
//out of memory
free(buffer);
buffer = NULL;
size = 0;
}
if(buffer)
{
//fill the buffer
}
//must always execute
*pBuffer = buffer;
*pSize = size;
}
int main(int argc, char const *argv[])
{
char* buffer = NULL;
size_t size = 0;
readstringbuffered(&buffer,&size);
if(buffer)
{
printf("%s",buffer);
free(buffer);
}
else
{
//error
}
return EXIT_SUCCESS;
}