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

时间:2019-11-21 17:15:47

标签: c malloc dynamic-memory-allocation realloc calloc

如何释放已在开始阶段重新分配并随后重新分配和重新分配的内存?这个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个块

4 个答案:

答案 0 :(得分:2)

您需要在<form id="courseform" name="courseform" class="fs-form fs-form-full" autocomplete="off" method="POST" action="{% url 'checkout' %}"> {% csrf_token %} <input type="hidden" name="useremail" value="{{useremail}}"> <input type="submit" value="Continue to Payment"/> </form> 返回的每个非NULL指针上调用free()。如果调用calloc(),则不应在传递给realloc()的参数的指针上调用free(),而应在指针上调用realloc() free()返回了。 (注意:正确使用realloc()是很棘手的,特别是如果您想正确处理错误时-除非绝对必要,否则我建议避免使用它

一个特别与您的代码有关的问题是:

realloc()

在第二行中,您用textInFile = (char *) realloc(textInFile, currentLength); textInFile = (char *) calloc(currentLength, sizeof(char) * currentLength); 返回的指针覆盖了textInFile的指针,从而失去了对calloc()返回的旧值的访问权限,因此您没有释放缓冲区的方法;因此您会发生内存泄漏。

答案 1 :(得分:0)

我认为..您误解了x ||= 0 x += 1 p x

realloc不是realloc

它返回分配的内存。

您的代码

free

textInFile = (char *) realloc(textInFile, currentLength); textInFile = (char *) calloc(currentLength, sizeof(char) * currentLength); free(ptr); 分配了两次。.第一个指针泄漏了。.

答案 2 :(得分:0)

答案:

ptr应该指向realloc,应该已经释放。在该问题中,由于textInFile的原始地址被覆盖,因此丢失了。

ptr = (char *) realloc(currentLine, currentLineLength);
currentLine = (char *) calloc(currentLineLength, sizeof(char) * currentLineLength);
free(ptr);

答案 3 :(得分:0)

此代码没有任何意义:

textInFile = (char *) realloc(textInFile, currentLength);
textInFile = (char *) calloc(currentLength, sizeof(char) * currentLength);

您为什么在calloc之后打电话给realloc?您认为该代码在做什么?如果您试图将扩展内存归零,那将无法正常工作。

如果要扩展(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失败,它将返回NULL,同时将当前缓冲区保留在原处,并且您将覆盖原始指针值(导致内存泄漏)。在知道操作成功之前,您也不想更新大小。最好将结果分配给临时指针,然后在确定成功后,将临时分配给原始指针。

您不必在致电calloc之后再致电realloc。最初分配缓冲区时,只需调用一次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-您仅使用它来存储临时值。