您的位置:首页 > 编程语言 > C语言/C++

C语言中的内存模型

2015-07-30 19:19 148 查看
写了好几年的程序了,大部分时候都是在用C++,剩下用了点java。用java的时候基本上没有考虑过内在模型的问题,因为使用频率并不高,也没有碰到过什么大的问题。用C++这么多年了,但是对内存模型其实还是说不了太清楚,好像很懂,但说的很清楚明白,能够通过代码证明我的方法,其实还是搞不定。说起来有点搞笑加心酸,但是是这样,整天写代码也未必是高手,就像整天开车也没能成赛车手一样。所以一直不停的努力,才可能成为高手,天天在那里写烂代码,不会提高什么水平的,只能腐朽下去。

先看一下APUE中的C内存空间分布图



其中low address在64位下的开始地址是0x0000000000400000,32位的程序,我现在基本上没有写了。

那么从低地址到高地址依次的段为:

1 第一部分是只读区,存放程序(.text)和文字常量(.rodata)。二进制代码和文字常量在内存中具体怎么个分布法,我不清楚。也有可能本身就是混着放的,需要一个证明的方法。代码区用来存放程序的二进制代码。常量字符串就是放在文字常量区,程序结束后由系统释放。

2 第二部分是可读写区,存放全局变量和静态变量。可读写区从低地址到高地址分成两个部分,第一部分是已经初始化的(.data),第二部分是未初始化的(.bss)。已经初始化的区域,从低地址到高地址,先是全局初始化的,后面是局部静态初始化的。未初始化区域,从低地址到高地址,先是局部静态未初始化的,后是全局未初始化的。

3 第三部分是堆区域,从低地址向高地址增加。

4 第四部分是栈区域,从高地址向低地址增加。

5 第五部分是命令行参数和环境变量。

6 第六部分是操作系统使用的区域。

以上的部分内容,是我从网上看到的,加上自己代码验证的,有不对的地方,请指正。详细的验证过程代码太多,就不在这里贴了。所以内存从低地址到高地址,各段分别是.text,.rodata,.data,.bss,heap,stack。以上的内存的分布情况,而C语言中那些东西放到什么地方,我们需要代码来看一下。

int g_a; // 全局未初始化区
int g_b = 0; // 全局初始化区
char* g_p1;  // 全局未初始化区
char* g_p2 = 0;  // 全局初始化区
int main()
{
static int d ; // 全局未初始化区
static int c =0;  // 全局初始化区

int a;// 栈区
int b = 0;// 栈区
char s[] = "abc"; // 栈区
char* p2;         // 栈区
char* p3 = "123456"; // "123456/0" 在常量区,p3在栈区

g_p1 = (char *)malloc(20); // 分配得来的20字节的区域就在堆区
strcpy(g_p1, "123456");    // "123456/0" 放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
return 0;
 }


注意的是:全局未初始化区的变量都被初始化为0
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: