S1E37:动态内存管理 课后作业

测试题:
0. 你看过 malloc 函数的原型是这样的 void *malloc(size_t size);,那你知道 size_t 实际上是什么类型吗?

答:size_t 为指针类型(大错特错

答案:size_t 实际上就是 unsigned int(无符号整型),在 64 位系统中是被定义为 long unsigned int。


1. 你知道 C 语言动态内存管理中最令人切齿痛恨的是什么吗?

答:申请内存后一定要主动释放内存

答案:使用 malloc 申请了内存空间,但用完之后没有用 free 及时释放空间。这就好比你家开了餐馆,但大家上厕所永远都不冲水那样让人讨厌。

2. 下面代码中,如果第一行打印的是“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。

3. 请问下面划红线位置应该填什么?

答:str = (char **)malloc(1024);(错误

答:str = (char *)malloc(1024);   (不理解答案,为什么)

4. 下面代码统计了程序在崩溃前一共调用了多少次 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 快捷键让它消停下来):h

请问这是为什么呢?

答:不清楚,知识范围外了~~(错误

答案:因为将每次申请堆内存空间的粒度调大,malloc 函数会直接返回 NULL 表示失败,这样程序既不会因为内存耗尽而崩溃,也不会退出死循环……

动动手:
0. 编写一个程序,让用户决定要录入的整数个数,然后再申请相应的内存空间来存放(要求使用 malloc 函数来申请内存空间)。
程序实现如下:

答:

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

int main()
{	
	int num,i;
	
	printf("请输入待录入整数的个数:");
	scanf("%d",&num);
	int *ptr = (int *)malloc(sizeof(int) * num);
	
	printf("\n请输入第1个整数:");
	scanf("%d",&ptr[0]);
	printf("\n请输入第2个整数:");
	scanf("%d",&ptr[1]);
	printf("\n请输入第3个整数:");
	scanf("%d",&ptr[2]);
	printf("\n请输入第4个整数:");
	scanf("%d",&ptr[3]);
	printf("\n请输入第5个整数:");
	scanf("%d",&ptr[4]);
	for(i=0;i<5;i++)
	{
		printf("\n你录入的整数是 %d", ptr[i] );	
		
	}
	free(ptr);
}

答案:

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

int main(void)
{
        int *ptr = NULL;
        int num, i;

        printf("请输入待录入整数的个数:");
        scanf("%d", &num);

        ptr = (int *)malloc(num * sizeof(int));

        for (i = 0; i < num; i++)
        {
                printf("请录入第%d个整数:", i+1);
                scanf("%d", &ptr[i]);
        }

        printf("你录入的整数是:");
        for (i = 0; i < num; i++)
        {
                printf("%d ", ptr[i]);
        }

        putchar('\n');

        return 0;
}

1. 坊间有传闻,说 malloc 最大可以申请 1GB 的内存空间……tU
但是,有的鱼油说可以成功申请到 2GB 的空间……
这样吧,咱自己写一个程序,计算 malloc 函数最大可以申请多少内存才能空间?

答:无

答案:

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

int main(void)
{
        void *block;
        int i, count;
        size_t maximum = 0;
        size_t blocksize[] = {1024 * 1024, 1024, 1};

        // 下面从大到小依次尝试
        // 先尝试以1024 * 1024为扩大粒度去申请内存空间
        // 当malloc返回NULL时,将扩大的粒度缩小为1024继续尝试
        // 最终精确到1个字节的粒度扩大maximum的尺寸
        for (i = 0; i < 3; i++)
        {
                for (count = 1; ;count++)
                {
                        block = malloc(maximum + blocksize[i] * count);
                        if (block)
                        {
                                maximum += blocksize[i] * count;
                                free(block);
                        }
                        else
                        {
                                break;
                        }
                }
        }

        printf("malloc在当前环境下申请到的最大空间是:%.2fGB\n", maximum * 1.0 / 1024 / 1024 / 1024);

        return 0;
}

  • 24
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值