《带你学C带你飞学习笔记》——SE37动态内存管理1

知识点回顾

1. 动态内存管理的几个函数

malloc -- 申请动态内存空间
free -- 释放动态内存空间
calloc -- 申请并初始化一系列内存空间
realloc -- 重新分配内存空间

2. 内存泄漏

导致内存泄漏主要有两种情况:

	隐式内存泄漏(即用完内存块没有及时使用free函数释放)
	丢失内存块地址

测试题

*0. 你看过 malloc 函数的原型是这样的 void malloc(size_t size);,那你知道 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. 请问下面划红线位置应该填什么?

char (*str)[1024];
str = ( ~~~~~~~~ )malloc(1024);

答:应该写char *。

  1. 下面代码统计了程序在崩溃前一共调用了多少次 malloc(1024):
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
        size_t count = 0;

        while (1)
        {
                malloc(1024);
                printf("%u\n", count++);
        }
}

答:电脑可运行内存除以1024次。

小甲鱼说他运行了一定的次数被系统killed了,增加粒度到101024反而在无限循环。而我实测结果是粒度为1024、101024、1001024都是无限循环,而粒度为10001024时电脑立即崩溃哦。

这是为什么呢?

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

动动手

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

#include<stdio.h>
#include<stdlib.h>
int main(void)
{
	int num, i;
	printf("请输入待录入的整数个数:"); 
	scanf("%d",&num);
	int *ptr = (int *)malloc(sizeof(int) * num);
	
	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]);
    }
	
	free(ptr);
	return 0;
 } 

评价:完美的代码,哈哈!

1. 坊间有传闻,说 malloc 最大可以申请 1GB 的内存空间……
但是,有的鱼油说可以成功申请到 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;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值