当前位置 博文首页 > Scissors_初夏的博客:初夏小谈:你不知道的malloc(0)
? ? ? ?在之前整理动态内存管理的知识时发现这样一个有意思的问题就是malloc(0),那么指向它的指针是空吗?还是什么?另外这片空间的大小到底是多少呢?
今天专门针对这个问题进行了详细的研究。发现malloc(0)是一个有效的分配内存的方法,但是它仅仅是返回一个指向一个未被使用的空间的地址,并且这块空间大小是0神奇吧。这就好比刻度尺上的刻度一样,我们量东西时会通过两个刻度之间的差距来说明它的大小。但是一个刻度能说明吗?显然不行。malloc(0)就像量东西只看一个刻度一样。
另外这片空间它是存在的只是大小为0罢了。它是不可以被使用的,如果你强行对指向这片空间的指针进行解引用那也可以这块数据依旧会放进去,不过它是不受保护的。如果强行放数据,那么一旦想释放这块空间就会程序崩溃。具体实例如下:
Windows下vs2017:
????#include<stdio.h>
#include<stdlib.h>
void Test()
{
int* ptr = (int*)malloc(0);
int size1 = sizeof(*ptr);
int size2 = sizeof(ptr);
*ptr = 123;
int Size = *ptr;
printf("Size = %d\n", Size);
printf("size1 = %d\n", size1);
printf("size2 = %d\n", size2);
size_t size0 =_msize(ptr);
printf("size0 = %d\n", size0);
free(ptr);
ptr = nullptr;
}
int main()
{
Test();
system("pause");
return 0;
}
结果:
显然程序直接崩溃!!!
如果不去使用这片空间就可以free掉指向这片空间的指针。
#include<stdio.h>
#include<stdlib.h>
void Test()
{
int* ptr = (int*)malloc(0);
int size1 = sizeof(*ptr);
int size2 = sizeof(ptr);
//*ptr = 123;
//int Size = *ptr;
//printf("Size = %d\n", Size);
printf("size1 = %d\n", size1);
printf("size2 = %d\n", size2);
size_t size0 =_msize(ptr);
printf("size0 = %d\n", size0);
free(ptr);
ptr = nullptr;
}
int main()
{
Test();
system("pause");
return 0;
}
结果显示:
Linux下centos7.0
但是在Linux下,如果强行使用这块空间然后去释放这块空间。那么它却不会奔溃
结果显示:
此外在Linux操作系统下,对于申请负整数个字节空间会崩溃,但是对于负浮点数却不会崩溃,而Windows下的vs2017却对负数直接崩溃。
对于已知指向动态申请的空间可以在windows下用_msize()去测试它到底占多大空间。
Linux下用malloc_usable_size测试空间大小。
针对malloc(-1)时程序崩溃原来是系统无法分配4G的内存空间(32位系统下),为什么呢?
这是因为每个进程会有4G的虚拟地址空间, malloc得到的的地址都是虚拟地址, 并且当malloc的时候, 操作系统并不会将实际的内存分配给进程的, 所以malloc只会占用进程自身的虚拟地址空间
分配这4G内存分别是①:第0G和第1G:用户态地址空间。②第2G:库函数映射等,③第3G:内核态内存空间,并且用户态地址空间可用内存不是连续的,第4G的空间是用户不可使用的。意思就是用户可用的就只有不到3G,并且不是连续的,意思就是一次性不能连续分配3G的空间。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 珍&源码
cs