C语言之下动态内存

#程序员自己管理的内存    X86 4G  堆区

申请内存          malloc            calloc

   扩容              realloc

释放内存           free

内存泄漏    检测工具 vld

* 1. 函数使用步骤

* 2. free 崩溃原因

*    1) 重复释放同一块内存 -> s=malloc  free(s); s=NULL;

*    2) 释放非堆区空间  int arr[]={1,2};free(arr);

*    3) 保存 堆区空间 起始地址的变量值  发生修改

*       int* p = malloc ...;

*       p++;

*       free(p);  p=NULL;

* 3. 面试: free函数 如何知道释放内存大小?

*    int*p = malloc();

*    p保存的地址 前 有指针 存储大小

void *p=malloc(1);            //无定义              1字节

(int*)malloc(1);      强转int类型

long long *

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {   //2G
       int *p=(int *)malloc(200);//申请200字节
       if (p == NULL) {
              printf("内存申请失败");
              exit(EXIT_FAILURE);
       }
       //用0初始化
       for (int i = 0; i < 50; i++) {
              p[i] = 0;
       }   //用for循环
       memset(p, 0, 200);    //memset 函数
       printf("%d", p[5]);
       free(p);
       return 0;
}

几个什么 

calloc(10,sizeof(int))     10个int类型大小

//用类型默认值0,初始化申请的内存  calloc
int main() {
       int *p=(int *)calloc(10,sizeof(int));  //40字节
              if (p == NULL) {
              printf("内存申请失败");
              exit(EXIT_FAILURE);
       }
              printf("%d", p[2]);
              free(p);
       return 0;
}

free 释放两次什么情况

程序崩溃 

1.防止出现此类错误   释放完之后  p=NULL
//用类型默认值0,初始化申请的内存  calloc
int main() {
       int *p=(int *)calloc(10,sizeof(int));  //40字节
              if (p == NULL) {
              printf("内存申请失败");
              exit(EXIT_FAILURE);
       }
              printf("%d", p[2]);
              free(p);     //野指针
              p = NULL;      //目的,防止多次释放同一块内存
              free(p);
       return 0;
}
2.释放的非堆区
// int *p=&val;
//free(p);   //释放堆区空间
3.释放超界 
int main() {
       int* p = (int*)malloc(100);
       assert(p != NULL);
       p++;
       free(p);
       p = NULL;
       return 0;
}

  free怎么知道释放多少    

 在这里你可能注意到,void free(void *ptr) 参数中只需要传入一个指针参数,就可以释放掉所分配的内存,它是如何确定指针所指向的区域分配了多大的内存空间呢?为了完成释放任务,很多内存分配函数都会在一个称之为头部指针(header,或者称之为头块)的地方保存一些额外的信息,头部指针通常在放回的内存块之前。
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.youkuaiyun.com/qq_41884002/article/details/121627852

int main() {
       int* p = (int*)malloc(100);
       assert(p != NULL);
       // [4B]   p->[100字节]
       
       free(p);
       p = NULL;
       return 0;
}

扩容 realloc

//realloc  扩容堆区
int main() {
       int* p = (int*)malloc(10 * sizeof(int));
       if (p == NULL) {
                           printf("内存申请失败");
                           exit(EXIT_FAILURE);
                     }
       p=(int *)realloc(p, 2 * 10 * sizeof(int));   //扩容  (什么,多大)
       free(p);
       p = NULL;
       return 0;
}

扩容底层实现

1>       100+100   在已经申请后直接加

100

2>     后边放不下   重新找一块空间   100+200

100(新)

100

3>  返回空指针,没有合适空间

 * realloc  使用步骤
*  //1. 申请堆区内存
*  //2. 扩容
*  //3. 内存释放
*   int* s = (int*)malloc(sizeof(int)*10);
*   if(s == NULL) return;
*   //需要扩容时
*   int* tmp = (int*)realloc(s,2*10*sizeof(int));
*   if(tmp == NULL)  //扩容失败   原先内存不需要释放
*   {
        free(s);    s = NULL; //释放原来内存
        return;
    }
    s = tmp;
*   //使用s所指的新大小空间
*   free(s);
*   s = NULL;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值