关于malloc(0) 和malloc(-1)的一些思考


解决这个问题,先要知道以下知识:

1. malloc(0)返回结果

ptr = malloc(0);

首先,要知道这个语句有没有问题,最好的方式就是自己跑一下程序;不过答案是,没有语法错误,甚至没有警告!

以下是我查到的关于返回的解答:

malloc() allocates size bytes and returns a pointer to the allocated memory. The memory is not cleared. If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().

意思就是:返回值要么是NULL,要么是一个可以被free调用的唯一的指针。

而经过实践,在window和linux上运行后,好像结果返回一个指针,且值大小不为NULL!(仅限于手头上的linux版本和window版本,不针对所有系统);

1.1 如何避免

既然知道了,返回的是一个指针,那么具体返回的什么意思;按理说是一个内存为0的空间?

从个人理解上来说,如果申请一个大小为0的空间,相当于你无法给这个空间进行赋值等操作;而返回一个非NULL指针,仅仅是让你在free的时候,不会产生错误;

官方的意思其实就是这样,为了避免对size的大小进行判断,使size=0的情况也返回一个指针,这样在free的时候就可以做到统一性;

所以,如何避免这个问题呢?其实,如果程序员手动申请内存的话,一般不会出现这个问题;而当size为形参进行申请内存后,size可能就是用户进行设置的,也就是说,在这里可能会导致size=0的情况出现。所以,只要在size>0的时候进行malloc,就可以避免这个问题。

1.2 代码运行结果

所有理论的知识都要进行实践;
所以,我用dev-c++进行测试;编译器版本是TDM-GCC 4.9.2 64-bit release;

int main(int argc, char *argv[]) {
	char *p;
	p = (char *)malloc(0);
	
	if(p==NULL)
		printf("get NULL\n") ;
	else
	{
		printf("get a valib value\n");
		printf("addr:%x\n",p);
		memcpy(p,"abc",2);
		printf("addr:%x is %d,%d\n",p,*p,*(p+1));
		free(p);
		printf("free success!");
	}
}

运行结果如下:
在这里插入图片描述
好了,从上面的结果分析出:

  1. malloc(0)返回的不是NULL;
  2. 居然能对申请地址0的空间进行操作,并且还能打印!
  3. 能free成功!

1.2 解析

首先,需要知道,malloc是从堆中使用链表进行申请的。所以申请的空间不单单是数据部分,还有一部分链表的头指针这些空间;

其次,malloc(0)申请到的空间,根据编译器不同,可能分给你的比你要申请的多。也就是说,虽然你申请0空间的内存,但是还是可以进行操作的。

所以,在上面的程序中,对p进行赋值,是可以打印的;

但是,多分配的空间又是多少?
这个,可以自己测试,每个平台申请的应该都不太一样;当使用的超过分配的大小以后,在进行free操作的时候,程序会崩溃;
以我手上的开发板测试情况来看(博通wifi芯片),malloc(0)返回一个有效地址,并且会申请16字节的空间!

可以参考:

https://www.cnblogs.com/xiaowenhu/p/3222709.html

2. malloc(-1)结果是什么?

答案是:不一定

2.1 解析

参考了其他人的博客,发现结果都不一样,有编译失败,有运行死卡死,我这里编译出来时返回NULL。
![
我这里大致可以看出,此结果和GCC编译器有关系,这里有一个-Walloc-size-larger-than=6选项和malloc的条件有关系,因此不能确定关系。

不过不用太过纠结,这个一般用于面试刷题用,正经人不会在项目中这么用,除非想作死!

3.杂记

很荣幸今天在面试的时候,面试官看到我这篇博客了,然后问我这个问题。但是由于太久没看这种偏向面试题的东西,大部分都已经忘了,实在很愧疚,自己写的自己居然忘记了。

今天再复习一遍,然后补充一下内容。

其实针对单片机的FreeRTOS来说,申请一个内存,其实有最小单位的,也就是内存管理结构体的大小,也就代表着,一般的malloc(0)和malloc(1)申请的大小是一样的(如果malloc(0)允许的话)。但是malloc(0)确实不怎么会出现在代码中,所以一般人确实容易忽略这个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值