如何释放分配和释放的内存?

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 - 您只是用它来存储临时值。