6.5 malloc(0)的问题

#include <iostream>
#include <vector>
#include <ctime>
#include<algorithm>
using namespace std;

namespace _nmsp1
{
	//malloc来分配0个字节
	void func()
	{
		char *p = (char*)malloc(0); 
		if (NULL == p)
			printf("got a NULL pointer\n");
		else
			printf("got a Valid pointer\n");//打印这句话,p有值
		*p = '\0';							//正常
		strcpy_s(p, 100, "这里是一个测试"); //正常
		free(p);							//报错

	}
}

int main()
{
	_nmsp1::func();
	return 1;
}

为什么free会报错?
当malloc分配内存时它除了分配我们指定SIZE的内存块,还会分配额外的内存来存储我们的内存块信息,用于维护该内存块。因此,malloc(0)返回一个合法的指针并指向存储内存块信息的额外内存,我们当然可以在该内存上进行读写操作,但是这样做了会破坏该内存块的维护信息,因此当我们调用free(ptr)时就会出现错误。
既然malloc另外分配内存来维护该内存块,也就是说分配来用于维护该内存块的内存的大小也是有限的,那么到底是多少呢?这和可能也依赖于实现,在ubuntu下,是24BYTE
ptr = malloc(0*sizeof(char)) ;ptr是局部指针变量,存储在栈中,它的值是动态分配的一块堆中的空间的首地址所以说这个地址是合法的,但是由于malloc的大小是0,故这个这个地址指向的堆中的存储空间的大小是0,这个指针类似于一个野指针,可以使用的,但是是有风险的,因为不知道这个指针后面的内存空间被谁使用着,要是被核心进程使用,哪肯定会造成相应程序的崩溃2…关于加上free后,程序会崩溃,我理解是由于在堆中并没有对应的空间分配到导致的~

测试代码:

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

int alloc_memory(char *p, int size)
{
	printf("\nbefore malloc %p\n", p);
	p = (char *)malloc(size);
	if (!p)
	{
		printf("malloc error  \n");
		return -1;
	}

	//len of malloc(0)
	printf("len of malloc(%d)  is  %d  ,the ture is %d\n", size, strlen(p), malloc_usable_size(p));

	//the first member 
	printf("the first member of malloc(%d) is %p:%d \n", size, p, *p);

	//set the first member
	*p = 10;
	printf("set the first member of malloc(%d) is %p:%d \n", size, p, *p);

	//memcpy
	memset(p, '\0', 12);
	memcpy(p, "01234567890123456789", 12);
	printf("after memcpy , the content is %s   len is %d  , the ture is %d \n", p, strlen(p), malloc_usable_size(p));

	free(p);
	p = NULL;

	printf("\n");
}


int main(int argc, char **argv)
{
	int size = -1;

	char *p = NULL;

	//malloc(0)
	size = 0;
	alloc_memory(p, size);
	printf("---------------------------\n");
	//malloc(5)
	size = 5;
	alloc_memory(p, size);

	
	return 0;
}

在这里插入图片描述
从测试结果来看,可以得出以下几个结论:

  1. malloc(0)在我的系统里是可以正常返回一个非NULL值的。这个从申请前打印的before malloc (nil)和申请后的地址0x562706602670可以看出来,返回了一个正常的地址。

  2. malloc(0)申请的空间到底有多大不是用strlen或者sizeof来看的,而是通过malloc_usable_size这个函数来看的。—当然这个函数并不能完全正确的反映出申请内存的范围。

  3. malloc(0)申请的空间长度不是0,在我的系统里它是24,也就是你使用malloc申请内存空间的话,正常情况下系统会返回给你一个至少24B的空间。这个可以从malloc(0)和malloc(5)的返回值都是24看出

  4. malloc(0)申请的空间是可以被使用的。这个可以从*p = 10; memcpy(p,“01234567890123456789”,12); 可以得出。但是是有风险的,因为不知道这个指针后面的内存空间被谁使用着,要是被核心进程使用,哪肯定会造成相应程序的崩溃

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值