数组存储数据结构的C内存释放

数组存储数据结构的C内存释放,c,memory,ansi,realloc,C,Memory,Ansi,Realloc,我正在写一个基于C的库,当涉及到使用free来释放内存块时,我有点困惑。。。 基本上,我有几个类似的结构是这样定义的: typedef struct { pthread_t thread_id; pthread_attr_t attr; void *data; size_t stacksize = NULL; } thread_info; 在这里,我基本上使用realloc为这个结构分配内存,并有一个数组指向它 我的问题是,如果我使用: free(my_

我正在写一个基于C的库,当涉及到使用free来释放内存块时,我有点困惑。。。 基本上,我有几个类似的结构是这样定义的:

typedef struct
{
    pthread_t thread_id;
    pthread_attr_t attr;
    void     *data;
    size_t stacksize = NULL;
} thread_info;
在这里,我基本上使用realloc为这个结构分配内存,并有一个数组指向它

我的问题是,如果我使用:

free(my_array[thread_index]); 
空闲调用是否会取消分配结构使用的内存以及其中的所有数据类型,即*thread\u id*、attr、data和stacksize也将取消分配,或者我必须单独取消分配它们,然后从数组中取消分配结构


对我来说,如果我在这样一个结构上使用free,那么其中包含的所有数据都将被释放,我不必显式地释放每个结构属性,但我只想确定情况是否如此。

您必须显式地释放结构中的资源,然后可以取消分配结构本身。如果您只解除分配结构,那么结构中的资源将不会解除分配,您将泄漏它们。

您必须显式解除分配结构中的资源,然后才能解除分配结构本身。如果只解除分配结构,内部资源将不会解除分配,并且会泄漏它们。

对于动态分配的结构,即数组、结构等的继承者,需要自下而上调用每个指针的free。您可以将此操作视为执行树的深度优先遍历


通常的限制适用于指向堆栈(而不是堆)上内存的指针的变量。例如,使用类型[n]、char[n]=“abc”等定义的变量与使用*alloc函数族从堆中分配的变量。还要注意的是,如果有多个指向同一地址的指针,对这些指针调用两次free是一个编程错误,但不一定是分段错误。

对于动态分配的结构,即数组、结构等的继承者,需要自下而上对每个指针调用free。您可以将此操作视为执行树的深度优先遍历

通常的限制适用于指向堆栈(而不是堆)上内存的指针的变量。例如,使用类型[n]、char[n]=“abc”等定义的变量与使用*alloc函数族从堆中分配的变量。还要注意的是,如果有多个指针指向同一地址,在这些地址上调用两次free是编程错误,但不一定是分段错误。

您需要使用malloc释放所有明确分配的数据。对malloc的每一次调用都与对free的调用进行了虚拟镜像

基本上,您可以定义一个构造函数来分配结构和结构内部的数据,以及一个析构函数来释放它。这可能类似于以下代码段:

int32_t         constructor(thread_info **t)
{
  if (NULL == (*t = malloc(sizeof (thread_info)))) {
    return -1;
  }

  if (NULL == ((*t)->data = malloc(sizeof (__data__)))) {
    return -1;
  }

  return 0;
}

int32_t         destructor(thread_info *t)
{
  if (free(t->data)) {
    return -1;
  }

  if (free(t)) {
    return -1;
  }

  return 0;
}
您需要使用malloc释放所有明确分配的数据。对malloc的每一次调用都与对free的调用进行了虚拟镜像

基本上,您可以定义一个构造函数来分配结构和结构内部的数据,以及一个析构函数来释放它。这可能类似于以下代码段:

int32_t         constructor(thread_info **t)
{
  if (NULL == (*t = malloc(sizeof (thread_info)))) {
    return -1;
  }

  if (NULL == ((*t)->data = malloc(sizeof (__data__)))) {
    return -1;
  }

  return 0;
}

int32_t         destructor(thread_info *t)
{
  if (free(t->data)) {
    return -1;
  }

  if (free(t)) {
    return -1;
  }

  return 0;
}

是类型为thread\u info[]或thread\u info*?thread\u info*registry=NULL的my\u数组;是类型为thread\u info[]或thread\u info*?thread\u info*registry=NULL的my\u数组;顺序很重要,因为如果您释放一个指向更多已分配内存地址的指针,则除非您有另一个指向该地址的指针,否则该已分配内存将不再可访问。本质上,如果你有一个空**foo,你已经分配给malloc等,你必须先释放**foo,然后再释放*foo。@Danathane我删除了这个问题,因为它突然出现在我的脑海中,有一个明显的答案,然后我看到了你的答案,因此,读者再次面临这样一个问题**为什么顺序很重要**?顺序很重要,因为如果您释放一个指向更多已分配内存地址的指针,那么该已分配内存将不再可访问,除非您有另一个指向它的指针。本质上,如果你有一个空**foo,你已经分配给malloc等,你必须先释放**foo,然后再释放*foo。@Danathane我删除了这个问题,因为它突然出现在我的脑海中,有一个明显的答案,然后我看到了你的答案,所以这个问题再次向读者提出**为什么顺序很重要**?