C Free()函数导致程序崩溃

C Free()函数导致程序崩溃,c,C,我目前正试图释放分配的内存,但是这样做会导致程序崩溃。一般来说,我对C语言和编程都是新手,如果能在这个问题上得到帮助,以及因我缺乏经验而产生的任何其他问题,我将非常高兴 Pool* allocatePool(int x); void freePool(Pool* pool); void store(Pool* pool, int offset, int size, void *object); typedef struct _POOL { int size; void* mem

我目前正试图释放分配的内存,但是这样做会导致程序崩溃。一般来说,我对C语言和编程都是新手,如果能在这个问题上得到帮助,以及因我缺乏经验而产生的任何其他问题,我将非常高兴

Pool* allocatePool(int x);
void freePool(Pool* pool);
void store(Pool* pool, int offset, int size, void *object);

typedef struct _POOL
{
    int size;
    void* memory;
} Pool;

int main()
{
    printf("enter the number of bytes you want to allocate//>\n");
    int x;
    Pool* p;
    scanf("%d", &x);
    p=allocatePool(x);
    freePool(p);
    return 0;
}

/* Allocate a memory pool of size n bytes from system memory (i.e., via malloc()) and return a pointer to the filled data Pool structure */

Pool* allocatePool(int x)
{
    static Pool p;
    p.size = x;

    p.memory = malloc(x);
    printf("%p\n", &p);

    return &p;//return the address of the Pool
}

/* Free a memory pool allocated through allocatePool(int) */
void freePool(Pool* pool) 
{
    free(pool);
    printf("%p\n", &pool);
}

您必须释放已分配的相同内存。在这里:

p.memory = malloc(x);
您将
x
字节分配给
p.memory
。这意味着:

free(pool);
printf("%p\n", &pool);
你应该释放同样的内存。您尝试
释放
池对象,但没有在堆上分配。在您的实现中,它是一个保存单个池的静态对象。试图
释放未在堆上分配的
内存是未定义的行为,在您的情况下是崩溃

上面的代码还显示了另一个关于
free
的误解:它不会更改分配内存的句柄。它仅将以前分配的字节标记为可再次使用。您的程序必须防止通过内存可用的指针访问内存

另外,
&pool
不是pool对象的地址,而是本地指针变量
pool
的地址

要修复崩溃,请将函数更改为:

void freePool(Pool *pool) 
{
    if (pool) free(pool->memory);
}

您必须
释放已分配的相同内存。你
malloc
p.memory
,但是你
free(&p)
,它根本不是堆中的内存,而是静态对象的地址。导致程序崩溃的决不是
free()
函数。您的代码中的一个bug导致程序崩溃。@SergeyA从来都不是很强大。这有点像说你永远不会被闪电击中。当然不太可能,但也不是说malloc/free的某个地方没有任何错误的实现。@Cubic,
-fpedantic
:)关于这种错误:使用系统的工具来帮助您。处于调试模式的Microsoft Visual Studio将以相当非正式的方式使您的程序崩溃。在Linux中,使用“valgrind”运行程序,它将报告错误的free()调用。仍然无法解决问题,因为main中的p现在指向不再有效的内存。错误@FredK,他将静态池的地址返回给main并将其传递给freePool。。。这里没什么问题。啊-错过了“静态”声明。仍然不是一个好的设计;如果他第二次调用allocatePool()而没有首先释放p内存,就会出现内存泄漏。@FredK:是的,设计很差
allocatePool
建议您可以获得多个池。OP对指针和分配的掌握还不是很好,所以这是这里首先要解决的问题。