zoukankan      html  css  js  c++  java
  • 动态内存分配( C语言,动态内存分配,栈区,堆区,静态区,常量区,代码区)

       动态内存分配 

     系统为了有效地管理内存, 把内存划分为:

        1.栈区

        2.堆区

        3.静态区(全局区)

        4.常量区

        5.代码区

        : 内存地址编号由高到低(栈区->代码区)

     

     1.栈区

        栈区的数据以栈的形势存储

        , 先进后出

        栈区存放的数据: 局部变量(定义在函数内部的变量)

        栈区的内存油系统自动管理的(分配内存, 回收内存), 不需要开发人员管理

        栈区只有8MB, 容易出现栈溢出

        stackoverflow网站

        栈区的内存, 函数结束时, 被收回

      int a = 10;//栈区分配4个字节 printf("栈区地址: %p ", &a); 

       2. 堆区

        由开发人员手动管理(申请内存, 释放内存)

        堆区空间比较大

        申请内存函数

        void  *malloc(<#size_t#>)

        返回值类型: void *, 空指针类型(泛指针类型), 可以转化成任意的指针类型

        函数名: malloc

        参数:  size_t, unsignedlong, 申请的字节数

     //从堆区申请4个字节的内存, 并返回首地址
        int *p1 = malloc(4);
        //向堆区存入数据1024
        *p1 = 1024;
        printf("%d
    ", *p1);
        printf("堆区地址: %p
    ", p1);
        
        //在堆区存入"iPhone 6s"
        char *p2 = malloc(10);
        strcpy(p2, "iPhone 6s");
        printf("%s
    ", p2);
        printf("堆区地址: %p
    ", p2);
        
        
        *p2 = 68;
        printf("%s
    ", p2);
        
        
        p2[3] = '';
        printf("%s
    ", p2);
    
        strcpy(p2 + 2, "abcd");//字符串最后一个是'', 会一起拷贝进去, 字符串结束
        printf("%s
    ", p2);
        
        strcpy(p2, p2 + 2);
        printf("%s
    ", p2);
        printf("%c
    ", p2[5]);

        内存泄露: 内存一直被占用, 而得不到释放    

        内存释放的函数

        void free(<#void *#>)

    int *p3 = malloc(4);//定义一个栈区指针变量, 存放栈区的首地址
        *p3 = 123;//把常量区的数据123, 拷贝到堆区
        free(p3);//把堆区的空间, 标记释放
        p3 = NULL;//因为指针p3存放有堆区的地址, 还可以通过地址访问堆区, 为了安全起见, 把指针p3置空
        
        //使用动态内存分配的知识, 在内存中存10个整数, 随机赋值[2, 10]
        int *p4 = malloc(sizeof(int) * 10);
        for (int i = 0; i < 10; i++) {
            //1
            *(p4 + i) = arc4random() % 9 + 2;
            printf("%d ", *(p4 + i));
            //2
    //         p4[i] = arc4random() % 9 + 2;
    //         printf("%d ", p4[i]);
            //3.
    //          *p4 = arc4random() % 9 + 2;
    //          p4++;
    //          printf("%d ", *p4);
    
        }
        printf("
    ");
        //冒泡排序
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9 - i; j++) {
                if (p4[j] > p4[j + 1]) {
                    int temp = p4[j];
                    p4[j] = p4[j + 1];
                    p4[j + 1] = temp;
                }
            }
        }
        
        for (int i = 0; i < 10; i++) {
            printf("%d ", p4[i]);
        }
        free(p4);
        p4 = NULL;
        printf("
    ");

     3.静态区(全局区)

        存放数据全局变量(定义在函数外部的变量静态变量(static修饰的变量)

        静态区的内存由系统控制

        静态区的内存一旦分配就一直占用直到程序结束

    #import <Foundation/Foundation.h>
    int d = 50;
    int main(int argc, const char * argv[]) {
     printf("静态区地址: %p
    ", &d);
        
        static int e = 70;//静态变量
        //a.存在静态区内
        printf("静态区地址: %p
    ", &e);
        
        //b.只会被初始化一次
        for (int i = 0; i < 10; i++) {
            static int n = 100;//只执行一次
            printf("%d ", n++);
        }
        printf("
    ");
        
        //c.不赋初值, 默认0
        static int f;
        printf("%d
    ", f);
        return 0;
    }

     4.常量区

        存放数据: 常量(1, 3.14, 'a', "iOS")

        常量区的内容只能读不能修改

        常量区由系统管理

        char *p = "iOS";
        printf("常量区地址: %p
    ", p);
        
        //*p = 'm';//error
        printf("%s
    ", p);

      //函数名就是函数的首地址 printf("代码区地址: %p ", hello); 

     5.代码区

        存放数据程序中的函数编译后的指令

        代码区由系统控制

    //函数名就是函数的首地址
        printf("代码区地址: %p
    ", hello);

     把字符串"1ab2c3d45e67g8h9"中的数字提取出来, 形成新的字符串, 新的字符串要求存放在堆区

      提示: 先求数字的个数, 再根据个数开辟内存空间

    char str[] = "1ab2c3d45e67g8h9";
        int count = 0;
        int i = 0;
        while (str[i] != '') {
            //判断字符是不是数字字符
            if (str[i] >= '0' && str[i] <= '9') {
                count++;
            }
            i++;
        }
        printf("count = %d
    ", count);
        
        //在堆区申请空间
        char *p5 = malloc(count + 1);
        //遍历字符串
        int j = 0;
        int k = 0;
        while (str[j] != '') {
            //判断字符是不是数字字符
            if (str[j] >= '0' && str[j] <= '9') {
                *(p5 + k) = str[j];
                k++;
            }
            j++;
        }
        //最后补上''
        p5[k] = '';
        printf("%s
    ", p5);
        free(p5);
        p5 = NULL;

        处理内存函数

        void *calloc(n, size)

        1.申请n * size个字节, 并返回内存的首地址, 申请到内存后, 会把内存中的数据清空

        2.比起maloc, 效率低, 安全性高

    int *p6 = calloc(10, sizeof(int));
        free(p6);
        p6 = NULL;

        void *realloc(p, size)

        1.从指针p的位置, 重新申请size个字节

        2.从指针p的位置开始申请, 如果后面有size个字节可以使用, 就直接申请; 如果没有, 就去内存中找一块连续size个字节, 找到就直接申请, 并且把之前申请的内存释放

    int *p7 = malloc(4);
        printf("%p
    ", p7);
        int *p8 = realloc(p7, 800);
        printf("%p
    ", p8);

        memset(p, c, n)

        从指针p的位置开始, 初始化n个字节的内容, 并且把内容设置为c

      char *p9 = malloc(4); memset(p9, 66, 2); printf("%s ", p9); 

        memcpy(p1, p2, n)

        从指针p2的位置开始, 向指针p1的位置, 拷贝n个字节的内容

        char str1[] = "ABCDEFG";
        char str2[] = "1234567";
        memcpy(str1 + 3, str2 + 4, 3);
        printf("%s
    ", str1);
        printf("%s
    ", str2);

        memcmp(p1, p2, n)

        比较p1p2指向的内存中的内容是否相等, 比较n个字节

        int *q = malloc(4);
        *q = 259;
        int *r = malloc(4);
        *r = 13;
        int result = memcmp(q, r, 2);
        printf("result = %d
    ", result);

    定义两个整型指针,分别用malloccalloc对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行赋值随机范围1-3,赋值后用memcmp比较两个数组。如果相同打印Good!否则打印Failed...

    //定义两个整型指针,分别用malloc、calloc对其分配空间保存3个元素
        int *m = malloc(sizeof(int) * 3);
        int *n = calloc(3, sizeof(int));
        
        //malloc分配的空间用memset清零
        memset(m, 0, sizeof(int) * 3);
        
        //随机对数组进行赋值随机范围1-3
        for (int i = 0; i < 3; i++) {
            *(m + i) = arc4random() % 3 + 1;
            *(n + i) = arc4random() % 3 + 1;
        }
        
        //打印数组m
        printf("
    数组m:
    ");
        for (int i = 0; i < 3; i++) {
        printf("%d ", *(m + i));
        }
        
        //打印数组n
        printf("
    数组n:
    ");
        for (int i = 0; i < 3; i++) {
            printf("%d ", *(n + i));
        }
        printf("
    ");
        
        //赋值后用memcmp比较两个数组
        int result1 = memcmp(m, n, sizeof(int) * 3);
        //如果相同打印Good, 否则打印Failed
        if (result1 == 0) {
            printf("Good!");
        } else {
            printf("Failed...");
        }

     

     

    The one who wants to wear a crown must bear the weight!
  • 相关阅读:
    五个Metro UI 风格的网页设计
    cocos2dx学习资料(转)
    Python性能鸡汤
    7款很棒的 HTML5 视频播放器
    优秀的后台管理界面设计案例分享
    Task的理解(转)
    超棒的20款javascript工具提示条(tooltips)类库(转)
    Xcode 证书生成、设置、应用(转)
    分享17个漂亮的电子商务网站(转)
    强烈免费25款商务logo设计模板(转)
  • 原文地址:https://www.cnblogs.com/OrangesChen/p/4833315.html
Copyright © 2011-2022 走看看