关于 malloc 函数和free 函数

原文链接:http://blog.youkuaiyun.com/zhangxaochen/article/details/8052128 


1. malloc 函数原型

void* malloc(unsigned int num_bytes);


函数接受一个无符号整形参数,表示需要申请的动态内存字节数; 返回值为void指针,一般往往需要强制类型转换,比如转为 char*。如果申请失败则返回 NULL。

2. malloc 的参数
大多数情况下,不要手动指定具体数值,比如如果希望申请 128 个int 长度的缓冲区,一般写作:

malloc(128*sizeof(int) );


这么写的好处有两点,一是系统无关,不必考虑在什么样的计算机上,int究竟占用几个字节(比如16、32位的计算机上int分别占2、4byte的区别,32、64位计算机的long分别占4、8 byte的区别); 二是语义明确,如果你写成 malloc(512),后面维护的时候,往往忘记这个究竟用来存储128个int呢,还是512个char。

3. malloc vs. new operator
c++ 的 new 至少与 malloc 有三点不同:
一是返回类型确定。二是自动计算实际内存空间的大小。三是内存自动初始化

举例说,比如申请 10 个 int 的 buffer,可以写成:

int* buf=new int[10];



也可以写成:

int* buf=(int*)malloc(10*sizeof(int) );


如前所述,new 不需要 (int*) 类型转换,也不需要手动 sizeof(int) 计算。同时, buf 指向的内存运行时会自动初始化为默认值, 注意,malloc 得到的内存,其数据是任意的,没有初始化。

这么一说, malloc 可以等价于 operator new(不是 new operator)。可以参考:

http://blog.youkuaiyun.com/zhangxaochen/article/details/8033503

4. malloc 用法规范

type* ptr;
if(NULL==(ptr=(type*)malloc(sizeof(type))) ){
 err("error happened");
 exit(1);
}
//do something....
free(ptr);
ptr=NULL;


5. 关于 malloc(0)
 linux 下允许 malloc(0) 这样的写法,因为 它默认限定了 malloc的下限为 16byte。 而像是 malloc(-1) 这样的写法是错误的

==========================================================
再谈 free:
1. free 原型:

void free(void* p);


2. free 释放内存,但不修改指针的值
 上面也提到过这样的代码:

free(ptr);
ptr=NULL;


free 释放了 ptr 指向的内存,但是ptr指向的地址并没有改变,所以使用 “ptr=NULL;” 来清空ptr,以免在之后误用 ptr而产生难以察觉的bug

3. free 如何释放内存? 怎么知道要释放的内存的长度?
存在即合理,malloc 肯定多做了什么。。。
传说 malloc 实际申请的内存,比传参时指定的内存要大一点。多了的内存存储了这样一个结构体:

struct mem_control_block {
    int is_available;    //这是一个标记?
    int size;            //这是实际空间的大小
};


is_available 解释下, 它告诉系统此内存是否可重新使用,比如 is_available=1; 就是把内存标记为 系统可用的。看下面代码,据说是free 的函数实现:

void free(void *ptr){
        struct mem_control_block *free;
        free = ptr - sizeof(struct mem_control_block);
        free->is_available = 1;
        return;
}


free 函数做了什么? 它并没有直接做“抹掉堆内存数据”之类的事情,仅仅是找到 mem_control_block 的位置, 标记 is_available=1, 就是申明“这块内存我不用了,系统可以收回去给别人用”这样简单的事情。而系统可以根据 mem_control_block 里的 size 记号判定收回多少字节的内存。
 

 原文链接:http://blog.youkuaiyun.com/zhangxaochen/article/details/8052128

{{OVER}}

### C语言中 `malloc` `free` 函数详解 #### 使用方法 `malloc` 是用于动态内存分配的库函数,在程序运行期间可以按需分配指定大小的内存块。此函数接受一个表示所需字节数的整数参数并返回指向新分配内存起始地址的指针。 ```c #include <stdlib.h> int* ptr; ptr = (int*)malloc(10 * sizeof(int)); if(ptr == NULL){ // Handle error } ``` 上述代码尝试为十个整型变量分配连续存储区域[^2]。 当不再需要之前通过 `malloc` 获取到的那部分堆区资源时,应当调用 `free` 来显式释放它所占用的空间以便后续重用这些位置上的物理地址: ```c free(ptr); // After freeing, do not use the pointer again without reassignment. ``` #### 区别 - **功能不同**:`malloc` 负责请求操作系统给予一定量的自由空间;而 `free` 则负责通知系统某片已使用的区间现在变为空闲状态可供其他对象获取。 - **参数差异**:前者接收单一尺寸参数以确定要创建的对象有多大,后者仅有一个形参即待销毁的目标实体首址(也允许传入空值)。 - **返回类型**:`malloc` 成功执行后会给出非零数值作为结果传递给外部调用者代表新的基地址,失败则反馈全零串;相反地,`free` 不会产生任何输出因为它本质上属于过程而非表达式。 #### 注意事项 为了防止潜在的风险以及保持良好的编程习惯,应该注意以下几点: - 动态分配出来的每一个区块都应有唯一对应的解除操作,确保两者数量相匹配,既不多也不少。多次释放同一段数据结构容易引发不可预见的问题甚至崩溃应用进程[^1]。 - 对于经由 `malloc` 得来的临时容器务必先验证其合法性再加以利用,避免因越界访问而导致非法指令异常中断正常流程。 - 解绑之后立即将关联句柄设回初始形态(通常是赋值成NULL),从而减少悬垂引用发生的几率,提高代码健壮性安全性[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值