首页 > 编程语言 > 详细

C语言内存四区模型分析

时间:2019-03-25 20:04:04      阅读:257      评论:0      收藏:0      [点我收藏+]

 

技术分享图片

图1-1

内存四区模型是C语言学习的一个重点也是一个难点,大多程序员往往注重代码的编写而不注重代码在执行中所进行的内存的变化而导致程序出现问题,严重时导致程序失控崩溃.

图1-1很直观的表示内存当中储存的数据类型,以及内存之间的关联。

1.C语言的内存区分

1.1 内存四区

1.1.1 代码区
代码区code,程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也叫代码段,这块内存是不可以在运行期间修改的。

1.1.2 静态区
所有的全局变量以及程序中的静态变量,以及字符串都存储到静态区, C编译器对于相同的字符串会自动进行优化分配为统一的地址。

1.1.3 栈区
栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出。

1.1.4 堆区
堆heap和栈一样,也是一种在程序运行过程中可以随时修改的内存区域,但没有栈那样先进后出的顺序。
堆是一个大容器,它的容量要远远大于栈,但是在C语言中,堆内存空间的申请和释放需要手动通过代码来完成。


2.C语言的内存分析

     1,下面对这这几区域进行分析。栈区 最重要的特性是先进后出的内存结构,当函数运行完成后,自动释放开辟给函数以及该函数的变量的内存,正是因为栈的这种特性使得变量有作用域的说法,main是程序的入口,可以理解为他是最先入栈的函数,所以他最后被释放。栈的方向(编译器给函数分配的地址)不一定是向上的(地址递增)也可能是向下(地址递减)。

2静态区的理解:

 1 #define  _CRT_SECURE_NO_WARNINGS 
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <stdio.h>
 5 
 6 char * getStr1()
 7 {
 8     char *p1 = "abcdefg2";
 9     return p1;
10 }
11 char *getStr2()
12 {
13     char *p2 = "abcdefg2";
14     return p2;
15 }
16 
17 void main55()
18 {
19     char *p1 = NULL;
20     char *p2 = NULL;
21     p1 = getStr1();
22     p2 = getStr2();
23 
24     //打印p1 p2 所指向内存空间的数据
25     printf("p1:%s , p2:%s \n", p1, p2);
26 
27     //打印p1 p2 的值
28     printf("p1:%d , p2:%d \n", p1, p2);
29 
30     printf("hello...\n");
31     system("pause");
32     return ;
33 }

分析以上代码发现指针所指的地址是一样,原因在于字符串是储存在静态区的,相同字符串,系统并不会重新开辟空间。这样做可以减少代码所占有的内存。

 3 堆(heap)与栈(stack)的区别

//堆区开辟内存
#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

//
char *getMem(int num)
{
    char *p1 = NULL;
    p1 = (char *)malloc(sizeof(char) * num);
    if (p1 == NULL)
    {
        return NULL;
    }
    return p1;
}


void main()
{
    char *tmp = NULL;
    tmp = getMem(10);
    if (tmp == NULL)
    {
        return ;
    }
    strcpy(tmp, "111222"); //向tmp做指向的内存空间中copy数据
    printf("hello..tmp:%s.\n", tmp);
    system("pause");
    return ;
}

//栈区开辟内存
define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

char *getMem1()
{
    char buf[64]; //临时变量 栈区存放
    strcpy(buf, "123456789");
    return buf;
}

void main()
{
    char *tmp = NULL;
    tmp = getMem1();
    if (tmp == NULL)
    {
        return ;
    }
    strcpy(tmp, "111222"); //向tmp做指向的内存空间中copy数据
    printf("hello..tmp:%s.\n", tmp);
    system("pause");
    return ;
}

堆区和栈区的不同在于函数运行后会不会自动的释放内存空间。栈会自动释放,所以代码2输出时乱码,因为buf地址中的内容在getnum1()运行完毕之后被释放了,所以buf地址的内容是乱码。而代码1开辟的空间是在堆区,所以不会自动释放内容。注意一般使用molloc()和free()这两个函数来开辟堆区的内存。

当开辟空间,不需要后要对内存进行释放。

 

内存空间的概念十分重要,影响了对指针的理解。而指针又是C语言的精髓。所以十分重要。

C语言内存四区模型分析

原文:https://www.cnblogs.com/Kroner/p/10596036.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!