一个程序的运行是需要内存的,那么我们平常写的程序的内存都是怎么分配的呢 (1)首先我们要知道,内存是真实存在的,内存是一个物理器件。它时由操作系统管理的,我们平常只要使用它就行了,为了方便管理。操作系统提供了很多种机制来管理内存,每一种机制都有其特点。 1.什么是栈?1.1.栈的特点 总结:a和b都是局部变量,都是栈内存,自动分配和释放 (2)栈内存反复使用。使用完后不会清零,这就是为什么每次分配局部变量若不初始化就是随机值的原因。 1 int a ; 2 printf("a = %d\n",a); 3 // a是随机值 (3)临时性:函数不能返回栈变量的指针。局部变量的地址是不能返回的。在一个函数内部分配的局部变量在函数结束时,其内存就已经不存在了。返回其地址是很危险的。 1 #include<stdio.h> 2 int * test(); 3 main() 4 { 5 int * w; //局部变量,栈上分配 6 w = test(); 7 *w = 20; 8 } 9 10 int* test() 11 { 12 int a = 10; //局部变量,栈上分配 局部变量,作用域为test函数,生命周期为test函数从执行到执行完毕 13 int *p = &a; 14 return p; 15 } 分析: (1)test函数能不能返回p的值? test函数中的a和p都是局部变量,作用域为test函数,生命周期为test函数从执行到执行完毕,当test函数执行完后,为a和p分配的栈上的内存已经释放了。也就是说,原来分配的地址已经不能在被a和p使用了。这里可以返回p的值,只是没有意义了,而是很危险的行为。 能访问,但可能会出错,原a的内存已经被释放,原来的地址已经不再属于a,这时候就会使程序崩溃。访问了不属于它的地址。 1 main() 2 { 3 int arr[5]; //局部变量,栈上分配 4 5 arr[10] = 100; 6 } 7
给arr数组分配了5个地址空间,访问第11个空间则会出错。 2.什么是堆?(1)操作系统堆管理器管理。堆管理器是操作系统的一个模块 1 //堆内存的使用范例 2 3 main() 4 { 5 int*p=(int *)malloc(1000*sizeof(int)); 6 } 7 //使用malloc()分配的内存是在堆上分配的 8 //这里的p仍旧是栈上分配,p是一个指针。该指针指向的内存是堆内存。(4000个字节的首四个字节) 9 3.数据区(1)数据段:(也被称作数据区、静态数据区、静态区)程序运行所需要的数据存放在这,比如函数执行过程中调用的一些变量(全局变量),产生的一些数据。注意:全局变量才算是程序的数据,局部变量算是函数的数据,局部变量不是程序的数据。 局部变量属于栈管理,在栈分配。 总结:(1)全局变量初始化为非0,存放在数据段。 4.代码段就是存放代码的地方,需要注意的是像char *p="aabbcc";这样的也会被分配的代码段,代码段的东西时不可以被修改的。 接下来我们看一个程序,具体分析,每一个变量存放在哪里 1 #include<stdio.h> 2 3 int test1 = 250 //全局变量,数据区 4 int test2 = 0 //初始化为0的全局变量,数据区的bss段 5 int test3 //未初始化全局变量,数据区的bss段 6 7 char * display();//代码段 8 9 void main() 10 { 11 12 int ok1 = 1; /* 局部变量 13 int ok2 = 0; 栈上分配 14 int ok3; */ 15 16 int * pre; //局部变量指针,栈上分配 17 pre = display(); 18 19 20 } 21 22 int * display(); 23 { 24 char * word = "he is goudan"; 25 //代码段 26 27 int * re = (int*)malloc(100*sizeof(int)); 28 //re指针在栈分配 29 //re指针指向的是内存在堆上分配 30 //当display()函数执行完毕后,re指针本身地址被释放, 31 //re所指向的堆内存依旧存在(若未保留该指针则内存泄漏) 32 return re; 33 } 34 35 总结: (1)程序经过编译后,分成不同的段,程序就是由好多个段组成的。数据段,代码段,bss段。
|
|
来自: 昵称70680357 > 《待分类》