看到一道面试题:
char * str;
if((str = (char *)malloc (0)) == NULL)
{
puts("Got a null pointer");
}else{
puts("Got a vaild pointer");
}
这里的问题是,str 得到的是NULL,还是一个准确的地址
在man手册里,是说如果malloc申请一个0 ,返回NULL,或者返回一个地址 根据不同的编译器结果也不一样。
我在网上看到了许多关于这个问题的讨论,基本都在说返回一个无效的地址。
还有些赞同一种说法:返回一个无效地址,但是对其进行操作时,仍然能写进去,并且这样解释:
当malloc分配内存时它除了分配我们指定SIZE的内存块,还会分配额外的内存来存储我们的内存块信息,用于维护该内存块。因此,malloc(0)返回一个合法的指针并指向存储内存块信息的额外内存,我们当然可以在该内存上进行读写操作,但是这样做了会破坏该内存块的维护信息,因此当我们调用free(ptr)时就会出现错误。
我做了相关测试:
char * str;
if((str = (char *)malloc (0)) == NULL)
{
puts("Got a null pointer");
}else{
puts("Got a vaild pointer");
}
*(str-1) = 'a';
*(str+0xff) = 'b';
printf("%c %c\n",*(str-1),*(str+0xff));
我这里并没有free
如果free,报错 Aborted (core dumped)
aborted 错误因为你释放了系统没有分配给你的空间.
那么 对于分配存储信息内存块的看法,我有了不同的想法。
系统对于堆空间的管理不像对于栈空间那么严格,堆空间是针对于用户开放的,而对于栈空间,即使栈空间满了,导致内存溢出,系统也不会占用堆空间飞陪给栈空间。
那么系统对于堆空间的管理 ,我有一种想法: 只记录你申请的堆空间的地址,和你使用过的堆空间的地址。
当你想释放堆空间的地址时,系统发现你所申请的地址和你所使用的地址不同,则会给你发出aborted错误,非法操作内存。
但是你不释放,系统就不会去查看。
但是这样操作还是很危险的,不释放会导致内存泄漏,以上仅仅作为个人想法,希望有知道真确的,有依据的答案,望广而告之。