在C中释放数组中结构字段的内存

时间:2015-04-07 12:27:27

标签: c arrays struct free

我正在用C编写一个函数,它将一个新的产品条目添加到一个结构数组中。该数组在以下结构中定义:

struct product_array {
    struct product *arr;
    unsigned int count; //Initially set to NULL, counts the number of entries
    };

数组是动态分配的,但每次添加新条目时都应重新分配。数组的每个元素都包含产品结构:

struct product {
    char *title;  
    char code[8]; // Should be truncated to 7 characters
   };

这就是我写的:

 void add_product(struct product_array *pa, const char *title, const char *code)


    {
        pa->arr = realloc(pa->arr, sizeof(struct product) * (pa->count + 1));
        if (pa->arr == NULL)
            return NULL;

        char *temp = malloc(strlen(title) + 1); // for title memory 
//should be dynamically allocated separately
        if (temp == NULL){
            return NULL;
        }

        memmove(temp, title, (strlen(title) + 1));
            title = temp;


        pa->arr[pa->count].title = title;

        int j = 0;
            while (*code) {
                pa->arr[pa->count].code[j] = (*code);
                code++;
                j++;
                if (j == 7)
                    break;
            }
        pa->arr[pa->count].code[j] = '\0';

        pa->count++;

     } 

它似乎工作正常(虽然我不确定我是否正确使用了realloc)。但现在我应该释放内存。我是通过写作来完成的:

free(pa->arr);

它似乎还可以。但是现在我应该释放为 title 分配的内存。要做到这一点,我应该改变main.c。

int main()
{
    struct product_array pa;
    pa.count = 0;
    pa.arr = NULL;

    add_product(&pa, "Product 1", "1111");

    add_product(&pa, "Product 2", "123320");

    add_product(&pa, "Product 3", "565496845");

}

在这里,我迷失了。

free (pa.arr->title);

似乎不起作用。

真的很感谢你的帮助。

3 个答案:

答案 0 :(得分:1)

在释放pa-> arr之前,你必须遍历数组,分别释放每个结构的标题,如下所示:

   for (int i = 0; i < pa.count; ++i)
   {
      free(pa.arr[i].title);
   }
   free(pa.arr);

答案 1 :(得分:0)

在你的main()类中,你分配了3个不同的'title'实例,当你去释放内存时,你需要释放3个不同的'title'实例。简单的答案是循环通过pa-&gt; arr并从每个成员中释放标题。

我在编写'C'时使用的一个技巧是创建一个解除分配结构成员的函数。然后,如果你在上面这样的数组中进行分配,你只需遍历调用free_()函数的数组来释放结构的所有成员。

void free_product(struct product *p) {
  free (p->title);
  /* If you dynamically allocate more fields in p, free them here */
}

void free_product_array(struct product_array *pa)
{
  int i;
  for (i = 0 ; i < pa->count; i++) {
    free_product(&pa->arr[i]);
  }
  free (pa->arr);
}

你的情况与我通常做的有点不同。我通常在函数末尾释放指针本身,但我不会这样做,因为你一次为产品条目分配了一个完整的数组。

答案 2 :(得分:0)

那里有很多问题。

使用realloc时要小心:如果你调用realloc()并且没有足够的空间来扩大内存分配指出它会将所有内容复制到新位置,可能是。因此,如果阵列是您希望更改它的大小,并且您没有在具有严格的内存大小限制的平台中工作,那么您应该以不同的方式执行此操作。例如:为500个条目分配一个空间,当它满了时,调用realloc将其增长到1000个条目。这样可以通过使用更多内存来节省一些处理能力(和内存带宽)。

另外,请确保了解内存分配的工作原理。一个很好的参考是http://www-bcf.usc.edu/~dkempe/CS104/08-29.pdf

例如,如果您致电:

free(pa->arr);

只是数组将被释放,所有标题仍然会在内存中分配,但是你丢失了对它们的所有引用。这称为内存泄漏(http://en.wikipedia.org/wiki/Memory_leak)。