你看过 malloc 函数的原型是这样的 void *malloc(size_t size);,那你知道 size_t 实际上是什么类型吗?
答:size_t 实际上就是 unsigned int(无符号整型),在 64 位系统中是被定义为 long unsigned int。
你知道 C 语言动态内存管理中最令人切齿痛恨的是什么吗?答:使用 malloc 申请了内存空间,但用完之后没有用 free 及时释放空间。这就好比你家开了餐馆,但大家上厕所永远都不冲水那样让人讨厌。
下面代码中,如果第一行打印的是“Before free, ptr = 0x8b23008”,请问第二行打印的是什么?
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *ptr = NULL;
ptr = (int *)malloc(sizeof(int));
if (ptr == NULL)
{
printf("内存分配失败!\n");
exit(1);
}
printf("Before free, ptr = %p\n", ptr);
free(ptr);
printf("After free, ptr = %p\n", ptr);
return 0;
}
答:第二行代码打印的是“After free, ptr = 0x8b23008”。有鱼油可能会疑惑:”难道调用 free() 函数释放内存后,ptr 不是应该指向 NULL 的吗?“。这里务必要注意一点,free() 函数释放的是 ptr 指向的内存空间,但它并不会修改 ptr 指针的值。也就是说,ptr 现在虽然指向 0x8b23008,但该空间已经被 free() 函数释放了,所以对于该空间的引用已经失去了意义(会报错)。因此,为了防止后面再次对 ptr 指向的空间进行访问,建议在调用 free() 函数后随即将 ptr 赋值为 NULL。
请问下面划红线位置应该填什么?
答:str = (char *)malloc(1024);
下面代码统计了程序在崩溃前一共调用了多少次 malloc(1024):
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
size_t count = 0;
while (1)
{
malloc(1024);
printf("%u\n", count++);
}
}
程序实现如下:
现在把每次申请对空间的粒度扩大为 10 * 1024:
……
while (1)
{
malloc(10 * 1024);
printf("%u\n", count++);
}
……
我们想着这样程序会不会快一点崩溃?
可程序反而陷入了死循环(使用 ctrl+c 快捷键让它消停下来):
请问这是为什么呢?
答:因为将每次申请堆内存空间的粒度调大,malloc 函数会直接返回 NULL 表示失败,这样程序既不会因为内存耗尽而崩溃,也不会退出死循环……