C/C++程序(常量字符串)内存分布
C/C++程序一般分为
1.程序段(text):程序段为程序代码在内存中的映射.一个程序可以在内存中多有个副本,通常为只读.
2.初始化的全局变量(data):在程序运行值初已经对变量进行初始化的
3.未初始化的全局变量(bss):在程序运行初未对变量进行初始化的数据,特点是:可读写的,在程序执行之前BSS段会自动清0。所以,未初始的全局变量在程序执行之前已经成0了。
4.堆(stack):存储局部,临时变量,在程序块开始时自动分配内存,结束时自动释放内存.存储函数的返回指针.
5.栈(heap):存储动态内存分配,需要程序员手工分配,手工释放.
网上搜到的、书中所讲的一般都如图所示,我比较疑惑的是char *p = "Hello"这种字符串常量所在区域,有一种说法是还有一段文字常量区 ,常量字符串就是放在这里的。这段常量区在哪里,原以为应该在text区域或之后,因为都是只读的区域,结果却很意外。
测试代码:
#include <stdio.h> #include <stdlib.h> #include <time.h> int gloUninit1; int gloUninit2; int gloInit1 = 1; int gloInit2 = 1; char * pStr1 = "Hello"; char * pStr2 = "World"; char * pStr3 = "Hello"; char * pStr4 = "more"; const int con = 1; char str[] = "Hello"; int Fun1(int a) { return a; } int Fun2(int a) { return a; } int main() { int (*pFun1)(int a); int (*pFun2)(int a); pFun1 = Fun1; pFun2 = Fun2; char * pStr5 = "this"; printf("gloUninit1 address: %d\n\ gloUninit2 address: %d\n\ gloInit1 address: %d\n\ gloInit2 address: %d\n\ const address: %d\n\ pStr1(hello): %d\n\ pStr2(world): %d\n\ pStr3(hello): %d\n\ Str(hello): %d\n\ Fun1 address: %d\n\ Fun2 address: %d\n\ pStr1(hello) address: %d\n\ pStr2(world) address: %d\n\ pStr3(hello) address: %d\n\ Str(hello) address: %d\n",&gloUninit1,&gloUninit2,&gloInit1,&gloInit2,&con,pStr1,pStr2,pStr3,str,pFun1,pFun2,&pStr1,&pStr2,&pStr3,&str); printf("(this)%d\n","this"); printf("(more)%d\n","more"); printf("(did)%d\n","did"); return 0; }
程序输出结果:
可以看出在内存低位的是函数地址,也就是text段。
紧接着text段的就是data段,可以看到初始化的全局变量按顺序排列开来,从gloInit1一直到Str,因为都是四字节的变量,可以看到内存地址也是按照4字节递增。
在往上就是常量区域了,常量con以及Hello,World,more,this这四个字符串的地址,可以看出编译器将相同的字符串优化到一处,所以pStr1和pStr3,pStr4和“more”的地址都是一样的,pStr1和pStr2相差6字节正好是“Hello”字符串长度,亦可以看出在分配int型常量con时进行了内存对齐。这里比较奇怪的是“did”字符串,依然在bss段之下,却和前几个字符串间隔了一段距离,和“this”的差别在于this之前有赋值给pStr5,有谁知道原因还望提点一二。
在往上就是bss段了。未初始化的全局变量存放在这里。
堆内存动态申请分配,栈由操作系统控制,分布如图示
转载于:https://www.cnblogs.com/ssmouse/archive/2013/01/21/2870614.html