程序执行时的内存分配

一、在程序执行期间,变量存储空间有三种:
1、静态存储区。内存在程序编译的时候就已经分配好了,这块内存在程序执行期间都存在,
存储全局变量和静态变量。
2、栈存储区。内存是在程序执行期间才分配的,函数内局部变量及函数参数的存储单元,当
函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率
高但容量小。
3、堆存储区。在程序执行时由程序员用malloc或new申请的内存,程序员自己负责何时用
free或delete释放分配的内存。频繁的分配和释放不同大小的堆内存将会产生堆内碎片。
二、程序将操作系统分配给它运行的内存分成五个区域:
1、栈区,存放局部变量,函数参数,返回数据,返回地址等。
2、堆区,由程序员分配及释放。
3、静态存储区,存放全局变量、静态变量和常量。具体由三部分组成:
  1>已初始化的全局变量和静态变量。
  2>未初始化的全局变量和静态变量。
  3>常量数据区。
4、文字常量区,程序中使用的常量字符串,程序结束后由系统释放。
5、程序代码区,存放函数体的二进制代码。
例1:

/////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>

int a=0; //存放在静态初始化区
const int b=2; //存放在常量数据区
static int val=10; //存放在静态初始化区
char *p1; //存放在静态未初始化区

void main(int argc,char *argv[])
{
int c; //存放在栈区
char s[]="sss"; //s存放在栈区,"sss"存放在常量区
char *p2; //存放在栈区
char *p3="hello"; //p3存放在栈区,"hello"存放在常量区
static int d=1; //存放在静态初始化区

p1=(char *)malloc(sizeof(char)*10); //存放在堆中
p2=(char *)malloc(sizeof(char)*10); //存放在堆中

strcpy(p1,"world"); //"world"存放在常量区
}

/////////////////////////////////////////////////////////////////////////////////////////////////////
例2:

/////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>

int main(int argc,char *argv[])
{
char *ptr="Hello";

*ptr='L';
printf("%s ",ptr);

return 0;
}
结果:
Segmentation fault
说明:“Hello”保存在常量区中,所以不能改变。

/////////////////////////////////////////////////////////////////////////////////////////////////////
例3:

/////////////////////////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>

int main(int argc,char *argv[])
{
char str[10]="world";
char *p=str;
*p='H';

printf("%s---%s ",p,str);

return 0;
}
结果:Horld---Horld
说明:变量str在保存栈中,即“world”在栈中,所以可以改变

/////////////////////////////////////////////////////////////////////////////////////////////////////

三、堆栈区别
栈:由系统自动分配,由编译器管理;申请效率高,但程序员无法控制;在函数调用中,第
一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后
是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变
量,当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的
地址,也就是主函数中的下一条指令,程序由该点继续运行。
堆:由程序员申请,由程序员管理;速度慢,且容易产生碎片,但程序员能够控制,使用方
便;一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

原文地址:https://www.cnblogs.com/Mr-Wenyan/p/7243660.html