美文网首页
C语言-内存四区

C语言-内存四区

作者: ty_Chen | 来源:发表于2020-02-27 18:14 被阅读0次

    内存总体被分为四大区域:堆区、栈区、全局区、代码区。每个区所存放的内容以及内容的声明周期不同。将内存进行区域划分有利于内存管理,从而提高对数据的处理效率。

    A. 全局区

    全局区也称为静态区,存放全局变量和静态变量,其中初始化的全局变量和静态变量存放在同一区块,未初始化的全局变量和静态变量存放在相邻的区块,程序结束后,由系统自动释放。

    1. 样例分析
    char * getStr1() {
        char *fp1 = "abcd";
        return fp1;
    };
    
    char * getStr2() {
        char *fp2 = "abcd";
        return fp2;
    }
    
      int main() {
        char *p = getStr1();
        char *q = getStr2();
        printf("p:%s, p:%p\n", p, p);
        printf("q:%s, q:%p\n", q, q);
    
        return 0;
    }
    
    2. 打印结果
    p:abcd, p:0x100b68f8e
    q:abcd, q:0x100b68f8e
    
    3. 内存分配图
    4. 分析:

    1、进入main函数
    2、在栈中创建char *变量p
    3、进入getStr1方法
    4、在栈中创建char *变量fp1
    5、字符串abcd属于静态变量,存储在全局区,且由系统进行释放。通过打印得知其地址值为0x100b68f8e
    6、将字符串的地址赋值给指针变量fp1,那么变量fp1则指向字符串所在的内存
    7、返回fp1的指针,并将该指针赋值给变量pgetStr1方法结束,fp1变量销毁,变量p指向字符串的所在的内存
    8、创建并赋值变量q的方式同于步骤2步骤7
    因此最后打印的结果是变量p内存存放的值与q相同,p指向的地址值也与q相同。

    B. 栈区:

    栈区由编译器自动分配释放局部变量和函数参数的值。

    1. 样例分析
    char * getStr3() {
        char str[] = "abcd";
        return str;
    };
    
    int main() {
        char *strp = getStr3();
        printf("strp:%s, strp:%p", strp, strp);
        return 0;
    }
    
    2. 打印结果
    strp:�M�y��7����, strp:0x7ffee691376b
    
    3. 绘制内存图
    4. 分析:

    1、进入main函数
    2、栈中创建strp变量
    3、进入getStr3函数
    4、栈中创建str变量
    5、全局区存入字符串abcd
    6、将全局区的字符串复制一份赋值给str变量
    7、返回str变量的地址,getStr3函数运行结束,str变量释放,将str的地址值赋值给变量strpstrp指向str的内存
    8、因str的内存已经被释放,所以str内存中的内容未知,故而乱码

    C. 堆区分析

    堆区由程序员手动创建和释放,若程序员未释放对应的变量,那么在程序结束后可能会被系统释放。

    1. 样例分析
    char * getStr4() {
        char *str = (char *)malloc(100);
         printf("str: %p\n", str);
            if (str == NULL) {
            return NULL;
        }
        strcpy(str, "abcd");
        return str;
    }
    
    int main() {
        char *strp1 = getStr4();
        if (strp1 != NULL) {
            printf("strp1:%s, strp1:%p\n", strp1, strp1);
            free(strp1);
            strp1 = NULL;
        }
        return 0;
    }
    
    2. 打印结果:
    str: 0x7fd490c02a70
    strp1:abcd, strp1:0x7fd490c02a70
    
    3. 内存图绘制
    4. 分析

    1、进入main函数
    2、栈区创建strp1变量
    3、进入getStr4函数
    4、栈区创建str变量
    5、堆区分配内存,并将分配好的内存地址赋值给str变量,str指向分配好的堆内存
    6、全局区分配字符串abcd的内存,并将其值复制一份赋值给堆中分配的内存
    7、返回str变量的值,getStr4函数结束,str变量释放,并将值赋值给strp1strp1指向堆中分配的内存
    8、打印结束后,释放堆中的内存

    D. 栈的生长方向和内存存放方向

    栈的生长方向:高字节 -> 低字节
    堆的生长方向:低字节 -> 高字节
    内存的存放方向: 低字节 -> 高字节

    相关文章

      网友评论

          本文标题:C语言-内存四区

          本文链接:https://www.haomeiwen.com/subject/wdxxhhtx.html