free()到底做了什么

1.问题

在LeetCode上做题偶然发现一道题:free内存后,还继续调用该指针,于是好奇,想了解free到底做了什么。

这段代码的free()掉了nextTemp结点的malloc内存,但后面还可以使用nextTemp = nextTemp->next。

2.原因

2.1 free的实现原理

操作系统在调用malloc函数时,会默认在malloc分配的物理内存前面分配一个数据结构,这个数据结构记录了这次分配内存的大小,在用户眼中这个操作是透明的。

那么当用户需要free时,free函数会把指针退回到这个结构体中,找到该内存的大小,这样就可以正确的释放内存了。

使用Linux的man手册查看(#man 3  free),只是说分配了之后需要free,并没有过多的说明:

The  free() function frees the memory space pointed to by ptr,
which must have been returned by a previous call to malloc(), calloc(), or realloc().  
Otherwise, or if free(ptr) has already been called before, 
undefined  behavior  occurs.
If ptr is NULL, no operation is performed.

2.2 回答

找了一些资料,发现的确是可以的,并且编译也不会报错,具体原因如下:

1)free只是释放了malloc所申请的内存,并没有改变指针的值;

2)由于指针所指向的内存空间已经被释放,所以其他代码有机会改写其中的内容,相当于该指针从此指向了自己无法控制的区域(无法控制这么说还是可以去使用的,只是危险),也成为野指针(野指针指指向一个已删除的对象或未申请访问受限内存区域的指针。与空指针不同,野指针无法通过简单地判断是否为NULL避免)。

3)为了避免错误,所以最好在free之后,使指针指向NULL。

根据原理的解释分析:free函数的作用只是告诉操作系统该内存不用了,可以收回,操作系统就把该内存链接到链接表上,

但是这段内存用户还是可以访问到的,只是该内存的值可能已经发生了变化。

  

3.总结

其实,free函数只是将参数指针指向的内存归还给操作系统,并不会把参数指针置NULL,为了以后访问到被操作系统重新分配后的错误数据,所以在调用free之后,通常需要手动将指针置NULL。从另一个角度来看,内存这种底层资源都是由操作系统来管理的,而不是编译器,编译器只是向操作系统提出申请。所以free函数是没有能力去真正的free内存的。只是告诉操作系统它归还了内存,然后操作系统就可以修改内存分配表,以供下次分配。

4.案列

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

int main()
{
    char *str = (char *)malloc(100);
    if(NULL == str)
    {
        printf("malloc failed !\n");
        return 1;
    }

    sprintf(str,"hello world");

    if(str != NULL) {
        printf("%p,%s\n", str,str);
    }

    free(str);

    if(str != NULL) {
        printf("%p,%s\n", str,str);
    }

    str = NULL;
    printf("%p,%s\n", str,str);//这里把它指向NULL
    /* 这里验证str为NULL时,free多次都是没有问题的,但不为NULL,则不行 */
    free(str);
    free(str);

    return 0;
}

结果输出:

### Linux `free -h` Command Usage and Explanation The `free` command provides a snapshot of the system's memory usage, including both RAM and swap space. When using `-h`, it displays all values in human-readable format (Kilobytes, Megabytes, Gigabytes). #### Syntax To use this command with human-readable output: ```bash free -h ``` This will display information about total, used, and available memory along with buffers/cache details. #### Output Columns Explained - **total**: Total installed physical or swap memory. - **used**: Memory currently being utilized by active processes. - **free**: Unused memory that is completely free to allocate immediately without needing any page eviction or swapping activity. - **shared**: Memory used by tmpfs (since version 3.18). - **buff/cache**: Sum of buffers and cache which can be quickly reclaimed when more memory is needed. - **available**: Estimation of how much memory is available for starting new applications without swapping out others; calculated from MemFree, Buffers, Cached, SReclaimable etc[^1]. For instance, running `free -h` might produce an output similar to below: ```plaintext total used free shared buff/cache available Mem: 7.7G 2.0G 4.9G 156M 804M 5.2G Swap: 2.0G 0B 2.0G ``` In this example, there are approximately 7.7 gigabytes of total RAM on the machine where around 2 gigabytes have been allocated while nearly 5 gigabytes remain unused but may still contain cached data ready for rapid reuse. --related questions-- 1. What does each column represent in the output of the `free -h` command? 2. How do buffer caches affect the reported amount of usable memory according to `free -h`'s results? 3. Can you explain what happens if my application requires more memory than shown under 'available'? 4. Is it normal for swap usage to increase even though plenty of RAM appears unallocated based on `free -h`? 5. Why would someone prefer checking memory status via `top` over simply using `free -h`?
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值