如何释放分配和释放的内存?
How to free reallocated and callocated memory?
如何释放一开始分配的内存,然后重新分配和分配?这个 ptr 是我的尝试,但是 valgrind 说已经有 6 个分配和 6 个释放,但是 3 个块中有 90 个字节肯定丢失了。
char *textInFile = (char *) calloc(currentLength + 1, sizeof(char) * currentLength);
char *currentLine = (char *) calloc(currentLength + 1, sizeof(char) * currentLineLength);
...
while ((textInFile[index] = getc(f)) != EOF) {
if (index > currentLength - 3) {
currentLength += 10;
ptr = textInFile;
textInFile = (char *) realloc(textInFile, currentLength);
textInFile = (char *) calloc(currentLength, sizeof(char) * currentLength);
free(ptr);
}
...
if (textInFile[index] == '\n') {
int k = 0;
for (int i = previousIndex; i < index; i++) {
if (k > currentLineLength - 3) {
currentLineLength += 10;
ptr = currentLine;
currentLine = (char *) realloc(currentLine, currentLineLength);
currentLine = (char *) calloc(currentLineLength, sizeof(char) * currentLineLength);
free(ptr);
}
...
index++;
}
...
free(textInFile);
free(currentLine);
==4426== 堆摘要:
==4426== 在退出时使用:3 个块中的 90 个字节
==4426== 总堆使用量:9 次分配,9 次释放,14,668 字节分配
==4426==
==4426== 泄漏摘要:
==4426== 绝对丢失:3 个块中的 90 个字节
==4426== 间接丢失:0 个块中的 0 个字节
==4426== 可能丢失:0 个块中的 0 个字节
==4426== 仍然可达:0 个块中的 0 个字节
==4426== 抑制:0 个块中的 0 个字节
我认为..你误会了realloc
。
realloc
不是 free
。
它returns分配内存..
你的代码
textInFile = (char *) realloc(textInFile, currentLength);
textInFile = (char *) calloc(currentLength, sizeof(char) * currentLength);
free(ptr);
textInFile
分配了两次。第一个指针泄露了。
您需要对 calloc()
返回的每个非 NULL 指针调用 free()
。如果你调用 realloc()
,那么你不应该在作为参数传递给 realloc()
的指针上调用 free()
,但你应该在指针上调用 free()
realloc()
返回。 (注意:正确使用 realloc()
是很棘手的,特别是如果你想正确处理错误——我建议避免它,除非它是绝对必要的)
你的代码有一个特别的问题是:
textInFile = (char *) realloc(textInFile, currentLength);
textInFile = (char *) calloc(currentLength, sizeof(char) * currentLength);
在第二行中,您用 calloc()
返回的指针覆盖了 textInFile
的指针,因此失去了对 realloc()
返回的旧值的任何访问权限,因此您无法释放该缓冲区;因此你有内存泄漏。
答案:
ptr
应该指向 realloc
应该被释放。题目中textInFile的原地址被覆盖掉了
ptr = (char *) realloc(currentLine, currentLineLength);
currentLine = (char *) calloc(currentLineLength, sizeof(char) * currentLineLength);
free(ptr);
这段代码没有任何意义:
textInFile = (char *) realloc(textInFile, currentLength);
textInFile = (char *) calloc(currentLength, sizeof(char) * currentLength);
为什么在 realloc
之后调用 calloc
?您认为该代码在做什么?如果您试图将扩展内存清零,那是行不通的。
如果你想扩展 (realloc
) 一个缓冲区,这里是这样做的一般过程。假设您将缓冲区分配为
T *buffer = calloc( number_of_items, sizeof *buffer ); // sizeof *buffer == sizeof (T)
对于某些类型 T
,您可以按如下方式扩展缓冲区:
T *tmp = realloc( buffer, (number_of_items + number_of_new_items) * sizeof *buffer );
if ( tmp )
{
buffer = tmp;
number_of_items += number_of_new_items;
}
else
{
// reallocation was not successful, handle as appropriate
}
通常,您不想将realloc
的结果分配给原始指针。如果 realloc
失败,它将 return NULL
同时保留当前缓冲区,您将覆盖原始指针值(导致内存泄漏)。在知道操作成功之前,您也不想更新尺寸。最好把结果赋给一个临时指针,确定成功后,再把临时赋给你原来的指针。
您不需要在调用 realloc
之后调用 calloc
。最初分配缓冲区时,只需调用 calloc
一次。你也可以使用 realloc
作为初始分配,你只需将 NULL
作为第一个参数传递:
T *buffer = realloc( NULL, number_of_items * sizeof *buffer );
编辑
将此应用于您的代码:
while ((textInFile[index] = getc(f)) != EOF) {
if (index > currentLength - 3) {
ptr = realloc(textInFile, currentLength + 10);
if ( ptr )
{
currentLength += 10;
textInFile = ptr;
}
else
{
// unable to extend textInFile
}
...
if (k > currentLineLength - 3) {
ptr = realloc( currentLine, currentLineLength + 10 );
if ( ptr )
{
currentLineLength += 10;
currentLine = ptr;
}
else
{
// unable to extend currentLine
}
}
完成后,您将获得自由
free( currentLine );
free( textInFile );
在此期间的任何时候您都不需要释放 ptr
- 您只是用它来存储临时值。
如何释放一开始分配的内存,然后重新分配和分配?这个 ptr 是我的尝试,但是 valgrind 说已经有 6 个分配和 6 个释放,但是 3 个块中有 90 个字节肯定丢失了。
char *textInFile = (char *) calloc(currentLength + 1, sizeof(char) * currentLength);
char *currentLine = (char *) calloc(currentLength + 1, sizeof(char) * currentLineLength);
...
while ((textInFile[index] = getc(f)) != EOF) {
if (index > currentLength - 3) {
currentLength += 10;
ptr = textInFile;
textInFile = (char *) realloc(textInFile, currentLength);
textInFile = (char *) calloc(currentLength, sizeof(char) * currentLength);
free(ptr);
}
...
if (textInFile[index] == '\n') {
int k = 0;
for (int i = previousIndex; i < index; i++) {
if (k > currentLineLength - 3) {
currentLineLength += 10;
ptr = currentLine;
currentLine = (char *) realloc(currentLine, currentLineLength);
currentLine = (char *) calloc(currentLineLength, sizeof(char) * currentLineLength);
free(ptr);
}
...
index++;
}
...
free(textInFile);
free(currentLine);
==4426== 堆摘要:
==4426== 在退出时使用:3 个块中的 90 个字节
==4426== 总堆使用量:9 次分配,9 次释放,14,668 字节分配
==4426==
==4426== 泄漏摘要:
==4426== 绝对丢失:3 个块中的 90 个字节
==4426== 间接丢失:0 个块中的 0 个字节
==4426== 可能丢失:0 个块中的 0 个字节
==4426== 仍然可达:0 个块中的 0 个字节
==4426== 抑制:0 个块中的 0 个字节
我认为..你误会了realloc
。
realloc
不是 free
。
它returns分配内存..
你的代码
textInFile = (char *) realloc(textInFile, currentLength);
textInFile = (char *) calloc(currentLength, sizeof(char) * currentLength);
free(ptr);
textInFile
分配了两次。第一个指针泄露了。
您需要对 calloc()
返回的每个非 NULL 指针调用 free()
。如果你调用 realloc()
,那么你不应该在作为参数传递给 realloc()
的指针上调用 free()
,但你应该在指针上调用 free()
realloc()
返回。 (注意:正确使用 realloc()
是很棘手的,特别是如果你想正确处理错误——我建议避免它,除非它是绝对必要的)
你的代码有一个特别的问题是:
textInFile = (char *) realloc(textInFile, currentLength);
textInFile = (char *) calloc(currentLength, sizeof(char) * currentLength);
在第二行中,您用 calloc()
返回的指针覆盖了 textInFile
的指针,因此失去了对 realloc()
返回的旧值的任何访问权限,因此您无法释放该缓冲区;因此你有内存泄漏。
答案:
ptr
应该指向 realloc
应该被释放。题目中textInFile的原地址被覆盖掉了
ptr = (char *) realloc(currentLine, currentLineLength);
currentLine = (char *) calloc(currentLineLength, sizeof(char) * currentLineLength);
free(ptr);
这段代码没有任何意义:
textInFile = (char *) realloc(textInFile, currentLength);
textInFile = (char *) calloc(currentLength, sizeof(char) * currentLength);
为什么在 realloc
之后调用 calloc
?您认为该代码在做什么?如果您试图将扩展内存清零,那是行不通的。
如果你想扩展 (realloc
) 一个缓冲区,这里是这样做的一般过程。假设您将缓冲区分配为
T *buffer = calloc( number_of_items, sizeof *buffer ); // sizeof *buffer == sizeof (T)
对于某些类型 T
,您可以按如下方式扩展缓冲区:
T *tmp = realloc( buffer, (number_of_items + number_of_new_items) * sizeof *buffer );
if ( tmp )
{
buffer = tmp;
number_of_items += number_of_new_items;
}
else
{
// reallocation was not successful, handle as appropriate
}
通常,您不想将realloc
的结果分配给原始指针。如果 realloc
失败,它将 return NULL
同时保留当前缓冲区,您将覆盖原始指针值(导致内存泄漏)。在知道操作成功之前,您也不想更新尺寸。最好把结果赋给一个临时指针,确定成功后,再把临时赋给你原来的指针。
您不需要在调用 realloc
之后调用 calloc
。最初分配缓冲区时,只需调用 calloc
一次。你也可以使用 realloc
作为初始分配,你只需将 NULL
作为第一个参数传递:
T *buffer = realloc( NULL, number_of_items * sizeof *buffer );
编辑
将此应用于您的代码:
while ((textInFile[index] = getc(f)) != EOF) {
if (index > currentLength - 3) {
ptr = realloc(textInFile, currentLength + 10);
if ( ptr )
{
currentLength += 10;
textInFile = ptr;
}
else
{
// unable to extend textInFile
}
...
if (k > currentLineLength - 3) {
ptr = realloc( currentLine, currentLineLength + 10 );
if ( ptr )
{
currentLineLength += 10;
currentLine = ptr;
}
else
{
// unable to extend currentLine
}
}
完成后,您将获得自由
free( currentLine );
free( textInFile );
在此期间的任何时候您都不需要释放 ptr
- 您只是用它来存储临时值。