C 语言:指针、free()与 NULL

本文通过实验探讨了free函数的行为,特别是其对指针值的影响。发现free函数不会将指针置为NULL,仅用于释放指针指向的空间。文章还提供了测试代码以验证这一结论。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明来源 http://blog.youkuaiyun.com/imred/article/details/44964425
  有时听人说,free 掉一个指针 ptr 之后,ptr 指向的空间会被释放掉,ptr也会被置为 NULL,所以程序中经常会有以下类似语句来判断指针是否指向可用的空间或者:

if (!ptr) {
    //do something
}

  但是最近在一个实验课中,有一些函数需要首先判断指针 ptr 指向的数据结构是否已经被建立,或者已经被销毁,然后再进行操作。理所应当地使用了上述语句。但程序中却出现了很多问题,经常是空间已被释放,但函数还是对这些空间进行了操作。经过分析,我把问题锁定在上面那些语句,然后写了一些代码来进行验证。

测试代码如下:

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

void test(int **ptr);

int main() {
    int a;
    int *ptr = &a;
    test(&ptr);

    ptr = (int *)malloc(10000000000*sizeof(int));   //分配一个超过我内存大小的空间
    test(&ptr);

    ptr = (int *)malloc(sizeof(int));
    *ptr = 0;
    test(&ptr);

    free(ptr);                      //释放掉分配的空间
    test(&ptr);

    ptr = (int *)malloc(sizeof(int));           //再次分配空间
    test(&ptr);

    return 0;
}

void test(int **ptr) {
    printf("ptr = %#x. ", *ptr);
    if (*ptr == NULL) printf("ptr is NULL\n");
    else printf("ptr is not NULL\n");
}

输出如下:

ptr = 0x8196039c. ptr is not NULL
ptr = 0. ptr is NULL
ptr = 0xa40008c0. ptr is not NULL
ptr = 0xa40008c0. ptr is not NULL
ptr = 0xa40008c0. ptr is not NULL

  从第二个 test() 输出可以看出,分配空间失败后,指针值被置为 NULL;但是从第四个 test() 输出可以看出,对指针进行 free 操作后,指针值并没有发生变化,并没有被置为 NULL;从最后一个 test() 输出可以看出,对指针再次分配空间时仍然分配了原来的空间,说明原来的空间已被释放,可以重新分配。
  由此得出,文章首的代码段仅适用与判断为指针分配空间是否成功,而不能判断为指针分配的空间是否已被释放。
  实际上,在 cplusplus.com 中我们可以找到以下关于free() 的说明:

void free (void* ptr);
Deallocate memory block

A block of memory previously allocated by a call to malloc, calloc or realloc is deallocated, making it available again for further allocations.

If ptr does not point to a block of memory allocated with the above functions, it causes undefined behavior.

If ptr is a null pointer, the function does nothing.

Notice that this function does not change the value of ptr itself, hence it still points to the same (now invalid) location.
转载请注明来源 http://blog.youkuaiyun.com/imred/article/details/44964425

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值