9、动态内存分配

存储区划分

内存管理:软件运行时对计算机内存资源的分配和使用的技术,其最主要的目的是高效、快速的分配、并在适当的时候释放和回收资源

内存分配方式

  • 从静态存储区域分配:内存在程序编译时已经分配好,这块内存在程序的整个运行期间都存在。例如:全局变量、static变量
  • 在栈上创建,在执行函数时,函数内局部变量的存储单元都可以在栈上创建,,函数执行结束后这些存储单元你自动被释放。栈内存分配运算内置于处理器的指令中,效率高,但能够分配的内存容量有限
  • 从堆上分配(动态内存分配),程序运行时用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存,动态内存的生存周期由程序员决定,使用灵活,但有许多缺点

这里写图片描述

静态内存分配(BSS段、数据段)

BSS段(Block Started by Symbol):

用来存放程序中未初始化的全局变量和静态变量,它不包含任何数据,只是简单地维护开始和结束的地址,即总大小,以便内存区能在运行时分配并有效地清零。BSS不占用磁盘空间,只在运行时占用。

数据段(data segment)

用来存放已初始化的全局变量和静态变量的一块内存区域,可以分为只读数据段和读写数据段,字符串常量等,但一般都放在只读数据段中

栈内存

用来存放程序临时创建的局部变量
栈内存
栈内存的错误使用

char *fun()
{
     //注意此处是把常量区的字符串“iphone”拷贝到栈内存中。
     char string[] = "iphone";
     return string;  //栈内存返回是不安全的,禁⽌!!!
}

常量区

//'a' 字符常量
//5 整形常量
//"iPhone" 字符串常量
//常量占⽤内存,只读状态,决不可修改!
char * string = "iPhone";
string[0] = 'a'; //运⾏崩溃!

静态存储区

  • 只初始化一次
  • 如果初始没给值,默认值为0
  • 只有程序退出才释放
  • 将变量定义的类型前加static,则该变量存储存储在静态存储区

堆区

malloc等内存分配函数分配的内存,手动分配,手动释放

代码区

用于存放程序执行代码的一段区域,所有的语句编译后会生成CPU指令存储在代码区


堆内存分配函数

动态内存分配

动态内存分配

void * malloc(unsigned size);//从内存的堆区分配大小为size个字节的连续内存空间
//如果内存分配成功,返回内存的首地址;失败则返回NULL
//从内存中申请一块空间,可以存储4个int类型的数据即共16个字节
    //赋值要求=两边的类型要一致,所以要进行一个强制转换,由默认的void * 转换为int *
    int *p = (int *) malloc(4*sizeof(int));  //16个字节
    //使用一个函数给malloc申请的空间进行初始化
    memset(p, 'A', 16);//中间的参数读的是ASCII码值,所以写0还是会出现奇怪的数,因此最好直接写一个字符
    if (p != NULL) {
        //申请成功要做的事
        //p中存放的是新申请的内存空间的首地址
        *p = 10;
        *(p+1) = 100;
        *(p+2) = 1000;
        *(p+3) = 10000;//存放4个整数
        //如果分配的空间未赋值,那么初始值会是垃圾数,不一定为0
    }else{
        printf("内存申请失败!\n");
    }
    for (int i = 0; i < 4; i++) {
        printf("%c\t",*(p+i));//循环结束后,p就不再指向刚才的首地址,而是指向其他未知空间,此时,就不要用p再进行其他操作了
    }

内存释放

void free(void *)//free函数的作用是释放内存,内存释放是标记删除

其他内存分配函数

calloc

分配n个size大小的空间,并且把该内存上的所有字节清零

void * calloc(unsigned n,unsigned size);
//calloc函数
    //格式:calloc(块数,长度)即分配块数个长度的内存空间
    //可以自动初始化为0,不需要memset了
    int *p = (int *)calloc(4,sizeof(int));
    if (p != NULL) {
        //申请成功要做的事
        //p中存放的是新申请的内存空间的首地址
        *p = 10;
        *(p+1) = 100;
        *(p+2) = 1000;
        *(p+3) = 10000;//存放4个整数
        //如果分配的空间未赋值,那么初始值会是垃圾数,不一定为0
    }else{
        printf("内存申请失败!\n");
    }

    for (int i = 0; i < 4; i++) {
        printf("%d\t",*(p+i));//循环结束后,p就不再指向刚才的首地址,而是指向其他未知空间,此时,就不要用p再进行其他操作了
    }

realloc

按给定的地址以及给定的大小重新分配

void *realloc(void *p,unsigned newSize);
//realloc函数:按给定的地址以及给定的大小给已经存在的空间进行扩展
    //格式:realloc(地址,新长度)
    int *p = (int *)calloc(4,sizeof(int));
    p = (int *)realloc(p,40*sizeof(int));//为了分配连续的空间,若当前空间不够,则会找新的足够大的空间,返回新的地址

    if (p != NULL) {
        //申请成功要做的事
        //p中存放的是新申请的内存空间的首地址
        *p = 10;
        *(p+1) = 100;
        *(p+2) = 1000;
        *(p+3) = 10000;//存放4个整数
        //如果分配的空间未赋值,那么初始值会是垃圾数,不一定为0
    }else{
        printf("内存申请失败!\n");
    }

    for (int i = 0; i < 40; i++) {
        printf("%d\t",*(p+i));//循环结束后,p就不再指向刚才的首地址,而是指向其他未知空间,此时,就不要用p再进行其他操作了
    }

内存操作函数

初始化内存

void *memset(void *s , int c , size_t n) ;//从s指向的内存开始初始化n个字节的内容为c

内存拷贝

void *memcpy(void *dest,const void*source , size_t n) ;//从source指向的内存开始拷⻉到dest,拷⻉n个字节

内存比较

int memcmp(const void *buf1, const void  *buf2, unsigned int count)
//⽐较buf1和buf2指向的内存是否相同,⽐较count个字节
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值