Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-在数组中使用malloc()存储指针,can';我不能事后释放他们_C_Arrays_Pointers_Memory Management_Malloc - Fatal编程技术网

C-在数组中使用malloc()存储指针,can';我不能事后释放他们

C-在数组中使用malloc()存储指针,can';我不能事后释放他们,c,arrays,pointers,memory-management,malloc,C,Arrays,Pointers,Memory Management,Malloc,我想将使用malloc()分配的指针存储在数组中,然后释放所有指针。然而,即使程序没有抱怨,它也不起作用。下面的cleanMemManager()实际上不会释放内存,因为在main()内部测试时,char*指针不是NULL,它将打印? 代码: #include <stdio.h> #include <stdlib.h> #include <string.h> void **ptrList = NULL; void tfree(void** ptr) {

我想将使用
malloc()
分配的
指针
存储在
数组中
,然后
释放
所有指针。然而,即使程序没有抱怨,它也不起作用。下面的
cleanMemManager()
实际上不会
释放
内存,因为在
main()
内部测试时,char*
指针
不是
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;
}
#包括
#包括
#包括
void**ptrList=NULL;
无效tfree(无效**ptr)
{
免费(*ptr);
*ptr=NULL;
}
void*talloc(整数大小)
{
void*ptr=malloc(尺寸);
ptrList[0]=ptr;///不知道这是否真的像我认为的那样
返回ptrList[0];
}
void initMemManager()
{
ptrList=(void**)malloc(sizeof(void**)*3);
memset(ptrList,0,sizeof(void**)*3);
}
void cleanmanager()
{
tfree(&ptrList[0]);//似乎没有释放正确的指针
}
int main()
{
initMemManager();
char*ptr=(char*)talloc(3);
cleanMemManager();
if(ptr!=NULL)//这将触发,我不希望它会触发
printf(“?”);
getchar();
返回0;
}

我不理解用于此的语法,指针实际上根本没有被触碰吗?既然不抛出任何错误,那么释放什么呢?

释放并不保证指向已分配块的指针将被设置为NULL。如果你真的尝试

if (ptrList[0] != NULL)
      printf("ptrList[0] != NULL");
您将看到程序不会输出,如果删除
cleanmemanager()
函数调用,它将输出。这意味着
tfree
功能按预期工作,释放分配的内存

至于为什么
ptr
变量没有设置为NULL,这仅仅是因为
ptr
仍在存储旧地址
cleanmemanager()
无法变异变量
ptr
。这通常称为悬空指针或释放后使用


另外,
free()
不会清除/归零分配的空间,该块仅被标记为“free”。数据很可能会在内存中保留一段时间,直到空闲块被另一个
malloc
请求覆盖。

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语言在这方面不是一种好语言


是的,sizeof(void*)这件事是我的错,我拿着一个三重指针胡闹,忘了把它恢复过来。感谢您提供其余信息。关于:
void*ptr=malloc(大小)1)始终检查(!=NULL)返回值以确保操作成功。2) 函数
malloc()
需要类型为
size\u t
not
int
的参数。(此隐式转换可能会失败,因为
size\u t
是无符号的,而
int
是有符号的。)