内存分配(Day-9)

计算机内存划分为5个区:栈区 堆区 静态区 常量区 代码区

1. 5大区:

  1. 栈区:
    1.1. 函数的参数或者是局部变量存储在栈区
    1.2. 局部变量:在函数 分支 循环的{}中定义的变量
    1.3. 栈区内存的管理方式:由系统负责分配和回收
    1.4. 定义变量时分配,函数执行结束后系统回收
    1.5. 内存被系统回收后,原来存储的数据没有被清空,只是标记回收
    1.6. 栈区存储的特点:先进后出 后进先出
    1.7. 入栈:定义变量在栈区分配存储空间,出栈: 回收内存
    1.8. 栈顶:后放进去的数据在栈顶 栈底:栈区内存起始的位置
    |_______栈顶_________| 高
    |____________________| |
    |____________________| |
    |_______栈底_________| 低

  2. 常量区(文字常量区):
    2.1. 常量区的内存管理:由系统分配和回收(程序结束运行时被回收)
    2.2. 常量区的数据只能被读取,不能被修改

  3. 全局变量:
    3.1. 使用关键字static修饰的变量 以及在函数外定义的变量(全局变量或者静态变量)
    3.2. 静态区的内存管理:由系统分配和回收(程序运行结束回收)
    3.3. 静态区的变量只能初始化一次,在编译时进行初始化
    3.4. 静态区的变量没有设置初始值时,默认值为:0

  4. 代码区:函数运行时存储的区域
    4.1. 代码区的内存管理机制:系统负责分配和回收
    4.2. 回收:程序运行结束后

  5. 堆区:
    5.1. 堆区的内存管理:开发人员负责分配与回收
    5.2. 回收:程序员自行回收
    5.3. void *malloc(size_t):

    指定分配的存储空间的大小(字节数), 将分配的存储空间的起始地址返回
    堆内存是使用地址操作,地址存储在对应的指针变量中
    void *malloc(<#size_t#>)
    /*
    void *:无类型指针
    malloc = memory (内存) allocation(分配)
    size 表示分配多大的存储空间,单位是字节
    */
    malloc返回的是地址,需要用指针获取

// 1. 动态分配int的空间   然后赋值
    int *p = malloc(sizeof(int));
    *p = 89;

// 2. 在堆中存储4个整型数
    int *p = malloc(sizeof(int) * 4);
    for (int i = 0; i < 4; i++) {
        *(p+i) = i;
    }
    for (int i = 0; i < 4; i++) {
        printf("%d   ",*(p+i));
    }

//3. 在堆中存储一个人名
    char *p = malloc(sizeof(char) * 20);
    strcpy(p, "zhangsanfeng") ;
    printf("%s  ", p);

//4. 随机产生10个30--45之间的随机数,存储在堆内存中
    int *p = malloc(sizeof(int) * 10);
    for (int i = 0; i < 10; i++) {
        *(p+i) = arc4random() % 16 + 30;
    }
    for (int i = 0; i < 10; i++) {
        printf("%d   ",*(p+i));
    }

例1:
有一个字符串,里面包含数字,提取出里面的数字,然后动态分配内存存储

    char p[] = "BJS150936";
    int len = (int)strlen(p);
    int count = 0;
    for (int i = 0; i < len; i++) {
        if (p[i] >= '0' && p[i] <= '9') {
            count++;
        }
    }
    printf("%d ",count);
    int *pi = malloc(sizeof(int) * count);
    int j = 0;
    for (int i = 0; i < len; i++) {
        if (p[i] >= '0' && p[i] <= '9') {
            pi[j] = p[i] - '0';//将字符转换为数字
            j++;
        }
    }
    for (int i = 0; i < count; i++) {
        printf("%d   ", pi[i]);
    }

5.4. free() 函数:内存释放是标记删除
内存泄露:分配空间之后,没有回收
野指针:指向了一个已经被回收的内存
malloc函数分配完空间之后,一定要进行释放,否则产生内存泄露的问题

    int *p = malloc(sizeof(int));
    *p = 20;
    free(p);
    printf("%d", *p); //  <---野指针:指向了一个被回收的内存
    // 刚释放的内存没有被使用,所以暂时没有报错  
    // 打印结果是:20

5.5 其他的内存分配函数:

// 1. void  *calloc(size_t, size_t);  第一个是申请几个   第二个是数据类型的字节
/*
calloc = clear allocation
 1. 在堆内存分配n个size字节的空间,并返回地址
 2. 会将分配的存储空间中原有的数据清空
*/

//1.1 在堆中存储5个整型数,范围是15--35之间的随机数
    int *p = calloc(5, sizeof(int));
    for (int i = 0; i < 5; i++) {
        p[i] = arc4random() % 21 + 15;
    }
    for (int i = 0; i < 5; i++) {
        printf("%d  ", p[i]);
    }
    free(p);  //  死也不能忘记释放内存呀!!!!!!  malloc  calloc都需要程序员释放的呀


// 2. void  *realloc(void *, size_t);   按给定的地址及给定的大小重新分配  释放新的内存, 旧的不用
    int *p = malloc(sizeof(10));
    int *ps = realloc(p, 20);
    printf("p = %p,  ps = %p\n", p, ps);

    /* 结果:p = 0x10020dd40,  ps = 0x10020ae70 给p重新分配20个字节,地址0x10020dd40不够20个,
    所以重新开辟了一块空间,分配20个给p。
    不用释放p,需要释放后来分配的空间---ps ~~~~~~~~~~
    */

5.6. 内存操作函数:


**初始化内存**

// 1.void *memset(void *s, int, c size_t n);  从s指向的地址开始,将n个字节初始化为int c
   int *p = malloc(sizeof(int));
   memset(p, 0, sizeof(int));

 ** 内存拷贝 **  
// 2.void   *memcpy(void *dest, const void *source, size_t n);从source开始,拷贝n个字节到dest
   char str1[] = "bjS140936";
   char str2[] = "15";
   memcpy(str1, "BJ", 2);
   memcpy(str1+3, str2, 2);
   printf("%s  ", str1);
   // 结果:BJS150936 

 ** 内存比较 **  
/* 3. int memcmp(const void *buf1, const void *buf2, size_t count);比较 buf1和buf2指向的内存是否相同,比较count个字节
*/

// 例3.1 定义两个整型指针,分别⽤malloc、calloc对其分配空间保存3个元素,malloc分配的空间⽤用memset清零,随机对数组进⾏行赋值随机范围1-3,赋值后⽤用memcmp⽐比较两个数组。如果相同打印Good!否则打印Failed...
    int *p1= malloc(sizeof(int) * 3);
    memset(p1, 0, sizeof(int) * 3);
    int *p2 = calloc(3, sizeof(int));
    for (int i = 0; i < 3; i++) {
        *(p1 + i) = arc4random() % 3 + 1;
        *(p2 + i) = arc4random() % 3 + 1;
     }
     int a = memcmp(p1, p2, sizeof(int) * 3);
     printf("%d  ",a); //  a<0  也就是Failed
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值