C中的动态数组无法释放内存

时间:2014-01-24 21:07:00

标签: c malloc free

g.content.array程序崩溃中释放freeArray期间。怎么了?

  #define STR_SHORT 256

    struct DirFileArray {
      struct dirFile *array;
      size_t used;
      size_t size;
    };

    struct dirFile
    {
        int  contentType ;
        char name [STR_SHORT];
        struct DirFileArray  content;
    };

    struct dirFile * getDirFile(char * fileName)
    {
        struct dirFile * f=  (struct dirFile *) malloc(sizeof(struct dirFile ) );
        f->contentType=TYPE_NONE;
        strcpy(f->name,fileName);
        f->content.array=NULL ;

        return f;
    };

void freeArray(struct DirFileArray *a) {
  if (a->array)
  {
  free(a->array);
  a->array = NULL;
  a->used = a->size = 0;
  }
}
    void insertArray(struct DirFileArray *a, struct dirFile * element)
    {

      if (a->used == a->size)
          {
          a->size ++;
          a->array =realloc(a->array, a->size * sizeof(struct dirFile));
          }
      a->array[a->used++] = *element;
    }

    void killDirFile(struct dirFile * value)
    {

        int i;
        for (i=0; i<value->content.used;i++ )
            {

            killDirFile( & value->content.array[i]);

            }

        printf("freeing array of %s\n", value->name);
        freeArray(&value->content);
        printf("freeing %s\n", value->name);

        free(value);
        value=NULL;

    }

    int main(void)
    {
        struct  dirFile * g  =  getDirFile("ggg");
        struct  dirFile * c  =  getDirFile("ccc");
        insertArray(&g->content,c);
        killDirFile(g);

    }

输出:

freeing array of ccc
freeing ccc
freeing array of ccc
freeing ccc
freeing array of ggg
*** glibc detected *** /home/pro/fff/Debug/updDown: corrupted double-linked list: 0x00000000006e9160 ***

3 个答案:

答案 0 :(得分:0)

看起来usedsize从未初始化。

答案 1 :(得分:0)

假设freeArray看起来像这样:

void freeArray(struct DirFileArray *content) {
    free(content->array);
}
你似乎两次释放同一个区域。

答案 2 :(得分:0)

您对killDirFile(g)的调用会递归调用其内容数组,然后您收到了freeing array of ccc条消息,然后通过调用freeing ccc释放元素本身free(value) ,内存区域属于g的内容数组的realloc()。除了原来的c内存不是免费的。

修复只会为struct dirFile *分配内存并直接存储指针,这样就不会有内存泄漏。

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

#define STR_SHORT 256

#define TYPE_NONE 0

struct DirFileArray {
    struct dirFile **array;
    size_t used;
    size_t size;
};

struct dirFile {
    int contentType;
    char name[STR_SHORT];
    struct DirFileArray content;
};

struct dirFile *
getDirFile (char *fileName)
{
    struct dirFile *f = (struct dirFile *) malloc (sizeof (struct dirFile));

    f->contentType = TYPE_NONE;
    strcpy (f->name, fileName);
    f->content.array = NULL;
    f->content.used = 0;
    f->contetn.size = 0;

    return f;
};

void
freeArray (struct DirFileArray *a)
{
    if (a->array) {
        free (a->array);
        a->array = NULL;
        a->used = a->size = 0;
    }
}

void
insertArray (struct DirFileArray *a, struct dirFile *element)
{

    if (a->used == a->size) {
        a->size++;
        a->array = realloc (a->array, a->size * sizeof (struct dirFile *));
    }
    a->array[a->used++] = element;
}

void
killDirFile (struct dirFile *value)
{

    int i;

    for (i = 0; i < value->content.used; i++) {

        killDirFile (value->content.array[i]);

    }

    printf ("freeing array of %s\n", value->name);
    freeArray (&value->content);
    printf ("freeing %s\n", value->name);

    free (value);
    value = NULL;

}

int
main (void)
{
    struct dirFile *g = getDirFile ("ggg");
    struct dirFile *c = getDirFile ("ccc");

    insertArray (&g->content, c);
    killDirFile (g);
    return 0;
}