我正在try 释放作为链接链一部分的不同 struct 所使用的内存. 函数dumpGroupingOrder()应该释放所使用的内存,但一旦使用,整个程序就会停止运行.如果没有它,即使存在内存泄漏,程序也可以正常运行,请参见下面的valgrind输出:

LEAK SUMMARY:
definitely lost: 48 bytes in 1 blocks
indirectly lost: 328 bytes in 11 blocks

有了它,没有内存泄漏,但我得到了一个double free or corruption (out)错误消息,以及来自valgrind的以下错误消息:

Invalid free() / delete / delete[] / realloc()
   at 0x48399AB: free (vg_replace_malloc.c:538)
   by 0x10929A: dumpGroupingOrder (code-stack.c:54)
   by 0x10952F: main (code-stack.c:88)
   Address 0x1fff0000b0 is on thread 1's stack
   in frame #2, created by main (code-stack.c:74)

下面是用作MWE的整个代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>


struct groupingOrder {
  int *taxa;
  size_t groupeSize;
  long double distance;
  struct groupingOrder* next;
};


void addGroup( struct groupingOrder* HEAD, int * groupe, size_t groupeSize, long double distance ) {

  struct groupingOrder* temp = HEAD;
  // Moving the last unit structure
  while( temp->next != NULL ) {
    temp = temp->next;
  }
  // Allocating space for the unit structure
  struct groupingOrder* nouveau = malloc( sizeof( struct groupingOrder ) );
  nouveau->distance = distance;
  nouveau->groupeSize = groupeSize;
  // Allocating variable space for the list of taxa to be stored
  nouveau->taxa = malloc( groupeSize * sizeof( int ) );
  for( int i = 0; i < groupeSize; i++) {
    nouveau->taxa[i] = groupe[i];
  }
  // Linking the new unit structure to the previous one
  temp->next = nouveau;
  // Specifying the NULL pointer to label the last unit
  nouveau->next = NULL;
}


void dumpGroupingOrder( struct groupingOrder* HEAD ) {

  struct groupingOrder* temp = HEAD;
  while( temp != NULL ) {

    // Copying the address of the current unit
    struct groupingOrder* dumpTarget = temp;
    // Storing the address of the next unit before dumping the
    //  current one.
    temp = temp->next;

    // Dumping the current unit and all its allocated variables
    if( dumpTarget->taxa != NULL ) {
      free( dumpTarget->taxa );
      printf( " #" );
    }
    free( dumpTarget );
    printf( "* " );
  }
}


void showGroupingOrder( struct groupingOrder* HEAD ) {

  struct groupingOrder* temp = HEAD;
  while( temp->next != NULL ) {
    temp = temp->next;
    for( int i = 0; i < temp->groupeSize; i++) {
      printf( " %d", temp->taxa[i] );
    }
    printf( " %Lf\n", temp->distance );
  }
}



int main() {
  
  size_t groupeSize[6] = { 2,2,4,2,5,7 };
  int groupes[][7] = { {2,3}, {5,1}, {2,3,5,1}, {7,4}, {2,3,5,1,6}, {2,3,5,1,6,7,4} };

  struct groupingOrder HEAD = { .next = NULL };
  
  for( int i = 0; i < 6; i++ ){

    addGroup( &HEAD, groupes[i], groupeSize[i], 0.0003 );
  }

  showGroupingOrder( &HEAD );
  printf( "\n\n" );
  dumpGroupingOrder( &HEAD );
  
  return 0;
}

推荐答案

正如在另一个答案中已经指出的,问题是您的链表的头 node 没有被malloc分配.因此,您不能在该 node 上呼叫free.

然而,与其他答案不同的是,我不建议您通过在释放内存时省略头 node 来解决问题,而是建议您重新构造程序,以便平等对待所有 node (包括头 node ),以便头 node 的内存也按malloc%分配:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>


struct groupingOrder {
    int *taxa;
    size_t groupeSize;
    long double distance;
    struct groupingOrder* next;
};


void addGroup( struct groupingOrder** HEAD, int * groupe, size_t groupeSize, long double distance ) {

    struct groupingOrder** temp = HEAD;
    // Make "temp" point to the "next" member of the last node of
    // the list, or if the list is empty, make "temp" point to
    // the pointer to the head node (which has the value NULL).
    while( (*temp) != NULL ) {
        temp = &(*temp)->next;
    }
    // Allocating space for the unit structure
    struct groupingOrder* nouveau = malloc( sizeof( struct groupingOrder ) );
    nouveau->distance = distance;
    nouveau->groupeSize = groupeSize;
    // Allocating variable space for the list of taxa to be stored
    nouveau->taxa = malloc( groupeSize * sizeof( int ) );
    for( int i = 0; i < groupeSize; i++) {
        nouveau->taxa[i] = groupe[i];
    }
    // Specifying the NULL pointer to label the last unit
    nouveau->next = NULL;
    // Linking the new unit structure to the previous one
    *temp = nouveau;
}


void dumpGroupingOrder( struct groupingOrder** HEAD ) {

    struct groupingOrder* temp = *HEAD;
    while( temp != NULL ) {

        // Copying the address of the current unit
        struct groupingOrder* dumpTarget = temp;
        // Storing the address of the next unit before dumping the
        //  current one.
        temp = temp->next;

        // Dumping the current unit and all its allocated variables
        if ( dumpTarget->taxa != NULL ) {
            free( dumpTarget->taxa );
            printf( " #" );
        }
        free( dumpTarget );
        printf( "* " );
    }

    // Mark linked list as empty
    *HEAD = NULL;
}


void showGroupingOrder( struct groupingOrder* HEAD ) {

    for ( struct groupingOrder* temp = HEAD; temp != NULL; temp = temp->next ) {
        
        for( int i = 0; i < temp->groupeSize; i++) {
            printf( " %d", temp->taxa[i] );
        }
        printf( " %Lf\n", temp->distance );
    }
}



int main() {
  
    size_t groupeSize[6] = { 2,2,4,2,5,7 };
    int groupes[][7] = { {2,3}, {5,1}, {2,3,5,1}, {7,4}, {2,3,5,1,6}, {2,3,5,1,6,7,4} };

    struct groupingOrder *HEAD = NULL;
  
    for ( int i = 0; i < 6; i++ ) {

        addGroup( &HEAD, groupes[i], groupeSize[i], 0.0003 );
    }

    showGroupingOrder( HEAD );
    printf( "\n\n" );
    dumpGroupingOrder( &HEAD );
  
    return 0;
}

我有必要修改函数mainaddGroup.我还修改了其他两个函数,但这些更改是不必要的.

该程序的输出如下:

 2 3 0.000300
 5 1 0.000300
 2 3 5 1 0.000300
 7 4 0.000300
 2 3 5 1 6 0.000300
 2 3 5 1 6 7 4 0.000300


 #*  #*  #*  #*  #*  #* 

C++相关问答推荐

C中空终止符后面的数字?

ISO_C_BINDING,从Fortran调用C

POSIX文件描述符位置

C指针地址和转换

为什么下面的递归基本情况在C中不起作用?

标准的C17标准是用括号将参数包装在函数声明中吗

MISRA C:2012 11.3违规强制转换(FLOAT*)到(uint32_t*)

从组播组地址了解收到的数据包长度

将常量转换为指针会增加.数据大小增加1000字节

每次除以或乘以整数都会得到0.0000

为什么数组的最后一个元素丢失了?

理解bzip2的BZ2_解压缩函数中的状态重新分配

我不知道为什么它不能正常工作,我用了get()和fget(),结果是一样的

C编译和运行

为什么<到达*时不会转换为>?

如何为avr atmega32微控制器构建C代码,通过光电二极管捕获光强度并通过串行通信传输数据

Makefile - 将 .o 文件放入子文件夹中

仅使用其内存地址取消引用 C 中的 struct

初始化动态分配的布尔二维数组的最佳方法是什么?

用于内存布局的size命令(文本、数据、bss)