C - 在数组中使用malloc()存储指针,之后不能释放它们

nur*_*tul 2 c arrays malloc pointers memory-management

我想存储pointers已经使用被分配malloc()arrayfree毕竟他们.然而,即使该程序没有抱怨它不起作用.下面cleanMemManager()实际上free没有内存,因为在main()char*中测试时pointer没有NULL,它将打印???.

码:

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

void **ptrList = NULL;

void tfree(void** ptr)
{
    free(*ptr);
    *ptr = NULL;
}

void* talloc(int size)
{
    void* ptr = malloc(size);
    ptrList[0] = ptr;   ///No clue if this actually does what I think it does
    return ptrList[0];
}

void initMemManager()
{
    ptrList = (void**)malloc(sizeof(void**) * 3);
    memset(ptrList, 0, sizeof(void**) * 3);
}

void cleanMemManager()
{
    tfree(&ptrList[0]); //Doesn't free the right pointer it seems
}

int main()
{
    initMemManager();
    char* ptr = (char*)talloc(3);
    cleanMemManager();

    if (ptr != NULL) //This will trigger and I'm not expecting it to
        printf("???");

    getchar();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我不明白用于此的语法,指针实际上根本没有触及吗?什么是释放,因为它不会抛出任何错误?

Eri*_*hil 5

main,char *ptr = (char*)talloc(3);声明ptr是一个局部变量.它包含由返回的值的副本talloc,并且您的子例程都不知道ptr它或它的位置.所以他们都没有改变它的价值ptr.因此,当你到达时if (ptr != NULL),价值ptr没有改变.

另外:

  • initMemManager,您应该sizeof(void *)在您拥有的两个地方使用sizeof(void**).在这些地方,您分配和复制void *对象,而不是void **对象.

  • 看起来你正在尝试实现一种智能内存管理器,NULL它可以在释放时自动设置指针.要在C中执行此操作,您必须放弃使用指针的副本.例如,ptr是一个副本ptrList[0],但tfree只设置传递给它的副本NULL.我们可以提供构建这样一个系统的建议,但很快就会变得很麻烦 - 你的内存管理器需要保存一个指针及其副本的数据库(以及从它们派生的指针,就像通过数组算术一样).或者你必须通过该ptrList数组间接引用所有内容,这会给你的源代码增加一些混乱.不幸的是,C不是一个好的语言.