程序编译后运行时的内存分配

参考文章之编译&运行
参考文章之执行程序时的内存分配方式&BSS段
参考文章之程序运行时的内存分配
参考文章之堆||栈

1.程序编译时的内存状况

编译时不分配内存。

编译器能够识别语法,数据类型等;然后逐行逐句检查编译成数据的.obj文件;然后再由连接程序将其连接成一个EXE文件//此时的程序以EXE文件的形式存放在磁盘上。

  • 编译只是一个扫描过程,进行此法语法检查,代码优化。
  • 编译只是根据声明时的类型进行占位,到以后程序执行时分配内存才会正确。换言之,声明是给编译器看的,聪明的编译器能根据声明帮你识别错误。
  • 编译程序越好,程序运行时就越高效

2. 程序运行时的内存状态

当执行这个EXE文件以后,此程序就被加载到内存中,成为进程。
此时一开始程序会初始化一些全局变量;然后找到入口函数(main()或者WinMain()),就开始按程序的执行语句开始执行。此时需要的内存只能在程序的堆上进行动态增加/释放了。

首先上个例子,慢慢阐述

int a = 0;//全局初始化区
char *p1;//全局未初始化区

int main()
{
	int b;//栈
	char s[] = "abc";//s[]在栈区,abc在常量区
	char *p2;//栈
	char *p3 = "123456";//p3在栈上,123456\0在常量区
	static int c = 0;//全局(静态)初始化区
	p1 = (char *)malloc(10);
	p2 = (char *)malloc(20);//分配得来10和20字节的区域就在堆区
	strcpy(p1,"123456");//123456\0在常量区,编译器可能会把p3所指向的"123456"优化在一起
}
  • 内存结构图示
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 内存不同区段说明
  1. text段
    即代码段,用来存放程序的代码(函数)和部分整数常量。只读。
  2. data段
    初始化过的全局变量数据段。包含初始化的静态变量,即全局变量和静态局部变量。该段的大小由程序源代码中值的大小确定,并且在运行时不会更改。用来保存初始化了的非0的全局变量,如果全局变量初始化为0,则编译有时会出于优化的考虑,将其放在bss段中。因为也是全局变量,所以在程序运行的整个生命周期内都存在于内存中。与bss段不同的是,data段中的变量既占程序运行时的内存空间,也占程序文件的储存空间。
    可读写,因为可以在运行时更改变量的值。
  3. BSS段
    用来存放没有被初始化或初始化为0的全局变量,因为是全局变量,所以在程序运行的整个生命周期内都存在于内存中。这个段中的变量只占用程序运行时的内存空间,而不占用程序文件的储存空间。
  4. heap堆区
    为成员分配和释放。
    heap(堆)是最自由的一种内存,一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。它与数据结构中的堆是两回事!分配方式倒是类似于链表。在C/C++中,用alloc系统函数和new申请的内存都存在于heap段中。
    eg:
int main()
{
	// C 中用 malloc() 函数申请
	char* p1 = (char *)malloc(10);
	cout<<(int*)p1<<endl;		//输出:00000000003BA0C0
	
	// 用 free() 函数释放
	free(p1);
   
	// C++ 中用 new 运算符申请
	char* p2 = new char[10];
	cout << (int*)p2 << endl;		//输出:00000000003BA0C0
	
	// 用 delete 运算符释放
	delete[] p2;
}

  1. stack栈区
    由编译器自动分配释放 ,存放函数参数值,局部变量的值(即临时变量)等。其操作方式类似于数据结构中的栈。
    通常栈是向下(即向低地址)增长的,当向栈中push一个元素,栈顶指针就会向低地址移动,当从栈中pop一个元素,栈顶指针就会向高地址移动。栈中的数据只在当前函数或下一层函数中有效,当函数返回时,这些数据自动被释放,如果继续对这些数据进行访问,将发生未知的错误。通常我们在程序中定义的不是用malloc系统函数或new出来的变量,都是存放在栈中的。
    eg:
int main()
{
	int b;				//栈
	char s[] = "abc"; 	//栈
	char *p2;			//栈
}

在这里插入图片描述
在这里插入图片描述

posted @ 2019-11-17 16:31  Moliay  阅读(29)  评论(0编辑  收藏  举报