【C】malloc(0)问题

实际上malloc(0)这个语法是对的,也确实分配了内存,但内存空间是0,就是说返回指针是不能用的。malloc(0)的返回值可能是NULL也可能不是NULL,和实参为一个正整数时没什么区别。如果返回值不为NULL,也应该用free()函数释放。malloc(0)唯一不同的地方就是,就算你申请内存成功,即malloc(0)返回值不为NULL,你也没法使用这块内存。

C语言参考手册》上说如果请求的长度为0,则标准C语言函数返回一个null指针或不能用于访问对象的非null指针

void *malloc(size_t size);

...

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

栈有自己的机器指令,是一个先进后出的数据结构。malloc分配的内存是堆内存,由于堆没有自己的机器指令,所以要有系统自己编写算法来管理这片内存,通常的做法是用链表,在每片被分配的内存前加个表头,里面存储了被分配内存的起始地址和大小,你的malloc返回的就是表头里的起始指针,这个地址是由一系列的算法得来了,通常不会为0,一旦分配成功,就返回一个有效的指针,对于分配0空间来说,算法已经算出可用内存的起始地址,但是你占用0空间,所以对那个指针操作就是错误的,操作系统一般不知道其终止地址,因为有占用大小就可以推出终止地址,还有就是即使分配0空间也要释放它,其实是释放的链表结点。还有,返回的指针是可用地址的起始地址,可用大小是固定的。(是多少?)

 

char *ptr;
if(int pp = (strlen(ptr=(char *)malloc(0))) == 0)
    puts("Got a null pointer");
else
    puts("Got a valid pointer");
char *ptr;
if(int pp = (sizeof(ptr=(char *)malloc(0))) == 4)
    puts("Got a null pointer");
else
    puts("Got a valid pointer");

如果求ptr的strlen的值和sizeof的值,该代码的输出是"Got a null pointer"。

第一段程序,此时malloc(0)返回了一个可用于free()释放的唯一指针(非NULL),而且将它传给strlen(),返回值为0,这样看来,它用'\0'进行填充的(即内容是NULL而非指针指向NULL)。 除此以外,顺便考察了strlen((char*)NULL)的行为:会导致段错误。
第二段程序呢,sizeof()里写了一大堆,其实只是计算了sizeof(char *),在32位机上结果当然是4,而sizeof()里面的malloc()根本没有执行。和前面两段代码不同,关键点不在malloc而是sizeof。


那么,如果给malloc()传一个负参数会怎么样?malloc()的参数是size_t类型,一般是无符号数,负值会被转化它对应于size_t中的对应值。当这个值大于malloc()所能分配的上限时,返回NULL

A size_t value is always positiveeven if you pass a negative value to malloc.The negative value is converted to an unsigned value of type size_t which leads to a huge positive value.

Example:

char *p = malloc(-2);

is equivalent to:

char *p = malloc(SIZE_MAX- 1);  // SIZE_MAX is the maximum

                                 // size_tvalue

猜你喜欢

转载自blog.csdn.net/shimadear/article/details/80291194
今日推荐