C语言 无法释放数组内的结构

mnemlml8  于 2023-03-29  发布在  其他
关注(0)|答案(1)|浏览(142)

我正在做一个项目,我试图操作一个包含一个结构体数组(WorkFiles)的结构体(WorkTree)。我试图做的是:
1.为工作树分配存储器,
1.为两个工作文件分配内存,
1.用工作文件填充工作树阵列,
1.解放一切。
据我所知,数组包含结构体本身,而不是指向它的指针,这似乎在free()函数中产生了问题。我不知道为什么,我尝试更改free()函数的参数,但没有任何成功。结构体本身是强加给我的,因此无法更改。下面是代码和valgrind消息。
谢谢你的帮助,非常感谢!

typedef struct {
    char* name;
    char* hash;
    int mode;
} WorkFile;

typedef struct {
    WorkFile* tab;
    int size;
    int n;
} WorkTree;

type WorkFile* createWorkFile(char* name)
{
    WorkFile* wf = (WorkFile*)malloc(sizeof(WorkFile));
    wf->name = strdup(name);
    wf->mode = 0;
    
    return wf;
}

int inWorkTree(WorkTree* wt, char* name)
{
    int i = 0;
    while(i < wt->n)
    {
        if(strcmp(wt->tab[i].name, name) == 0) 
    {
        return i;
    }
    i++;
    }
    return -1;
}

int appendWorkTree(WorkTree* wt, char* name, char* hash, int mode)
{ 
    int res = inWorkTree(wt, name);
    
    if(res == -1)
    {
        WorkFile* new = createWorkFile(name);
    new->hash = strdup(hash);
    new->mode = mode;
    wt->tab[wt->n] = *new;
    wt->n = (wt->n) + 1;
    return 1;
    }
    
    return -1;
}

WorkTree* createWorkTree(int size)
{
    WorkTree* wt = (WorkTree*)malloc(sizeof(WorkTree));
    wt->tab = (WorkFile*)malloc(sizeof(WorkFile)*size);

    wt->n = 0;
    wt->size = size;
    
    return wt;
}

void freeWorkTree(WorkTree* wt)
{
    int i = 0;
    
    while(i < wt->n)
    {       
        free((&(wt->tab[i]))->name);
    free((&(wt->tab[i]))->hash);
    free(&(wt->tab[i]));
    i++;
    }

    free(wt->tab);
    free(wt);
}

以下是我的主要功能:

int main()
{
    WorkTree* wt = createWorkTree(2);

    appendWorkTree(wt, "test", "blablabla", 12);
    appendWorkTree(wt, "test1", "bloublou", 10);

    freeWorkTree(wt);
    
    return 0;
}

以下是Valgrind的信息:
valgrind_memory_check

bgtovc5b

bgtovc5b1#

您在此处分配的数组:

wt->tab = (WorkFile*)malloc(sizeof(WorkFile)*size);

在C语言中,这是一个单独的内存块,并且必须作为一个块释放。内容由您管理,尽管编译器会告诉您元素的大小,以便您可以使用[]进行索引。如果您想要删除中间的一个元素,则需要代码来移动剩余的元素以填充漏洞,或者有某种方法将该内存标记为“未使用”。
C有一个函数realloc(),它将从malloc()获取一个指针和一个新的大小,并返回一个指向新内存的指针,其中的内容被复制。如果你需要在末尾添加元素,或者如果你想通过从末尾删除元素来截断,它会很有用,但当然它正在执行复制操作,所以有开销。你可以将最后一个元素,把它复制到你想要删除的元素上,然后是realloc()内存,它比sizeof(WorkFile)*size-1)小1个元素。这会改变顺序,所以如果它是排序的,那就不起作用了。

相关问题