Chinaunix首页 | 论坛 | 博客
  • 博客访问: 447893
  • 博文数量: 26
  • 博客积分: 15
  • 博客等级: 民兵
  • 技术积分: 300
  • 用 户 组: 普通用户
  • 注册时间: 2012-11-28 11:38
文章分类

全部博文(26)

文章存档

2020年(2)

2015年(3)

2014年(16)

2013年(1)

2012年(4)

我的朋友

分类:

2012-11-28 11:46:20

原文地址:C与C++内存机制的不同 作者:licong0527

C与C++的内存机制虽然非常相似,但还是有一些不同的地方。下面让我们一起来看看它们到底有什么区别吧。

(一)C内存机制
1. 栈(Stack):
        位于函数内的局部变量(包括函数实参),由编译器负责分配释放,函数结束,栈变量失效。

2. 堆(Heap) :
        由程序员用malloc()/calloc()/realloc()分配空间,free()释放所申请的空间。如果程序员忘记free(),则会造成内存泄漏,程序结束时可能会由操作系统回收,也许就一直占用着直至关机。

3. 全局区/静态区(Global Static Area): 
        全局变量和静态变量存放区,程序一经编译好,该区域便存在。并且在C语言中初始化的全局变量和静态变量和未初始化的放在相邻的两个区域(在C++中,由于编译器会给全局变量和静态变量自动初始化赋值,所以没有区分了)。由于全局变量一直占据内存空间且不易维护,推荐少用。程序结束时释放。 

4. C风格字符串常量存储区:
        专门存放字符串常量的地方,程序结束时释放。

5. 程序代码区:
        存放程序二进制代码的区域。
 
(二)C++内存机制
1. 栈(Stack): 
        位于函数内的局部变量(包括函数实参),由编译器负责分配释放,函数结束,栈变量失效。

2. 堆(Heap): 
        这里与C不同的是,该堆是由new申请的内存,由delete负责释放。

3. 自由存储区(Free Storage): 
        由程序员用malloc()/calloc()/realloc()分配空间,由free()释放。如果程序员忘记free()了,则会造成内存泄漏,程序结束时可能会有操作系统回收,也许就一直占用着直至关机。
        与C的堆机制对应

4. 全局区/静态区(Global Static Area): 

         全局变量和静态变量存放区,程序一经编译好,该区域便存在。在C++中,由于编译器会给全局变量和静态变量自动初始化赋值,所以没有区分初始化和未初始化变量。由于全局变量一直占据内存空间且不易维护,推荐少用。程序结束时释放。


5. 常量存储区:

          这是一块比较特殊的存储区,专门存储不能修改的常量(如果采用非正常手段更改,当然也是可以的)。


举个例子来说明一下C和C++在全局区/静态区的区别:

(1)C程序:

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. static int a;
  3. int b;
  4. int c = 7;

  5. int
  6. main(void)
  7. {
  8.     return 0;
  9. }
将.c源文件编译链接,生成可执行文件,打印一下文件的大小如下:

可以看到,数据段(不包括bss)大小为256,bss(未初始化数据段)大小为16。


接下来,我们对b进行初始化,代码如下:

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. static int a;
  3. int b = 9;
  4. int c = 7;

  5. int
  6. main(void)
  7. {
  8.     return 0;
  9. }
可执行文件空间分配如下:


可以看到,数据段(不包括bss)大小为260,bss(未初始化数据段)大小为12。

       与上面的那段代码对比可以发现,data增加了4,刚刚好是bss减少的4。现在,就可以确定C语言中,对全局区/静态区中变量初始化与为初始化是放在不同区域的。


特别注意:

我在编译的时候增加了一个选项-std=c89。为什么要增加这个选项呢?

最开始我编译上面的程序没有加-std=c89这个选项,以gcc 1.c进行文件编译,无论变量b是未初始化还是初始化了,

size a.out打印出来的结果都没有变化。

而让人奇怪的是,一模一样的程序在郑康的机子上却打印出有变化的结果,这让我们感觉很奇怪。

我们都gcc -v查看了自己的gcc版本,发现都是一样的4.6.3。

那是为什么呢?后来发现我装了g++,而郑康的没有装,我就在想会不会是这个原因呢?可是后来发现还是不是的。

后来突然想起来,以前有一个程序,我的电脑支持动态数组,而郑康的不支持。因为它的是c89标准,而我的是c99标准,c99中增加了很多C++的特性在里面。

于是我在编译的时候增加了一个选项-std=c89,果然文件大小分配出现了变化。所以,如果各位的机子上出现了和我一样的结果,那很有可能是标准问题哦!


说了这么多,我们来看看c++程序的运行结果吧。

b未初始化:

b初始化后:

这次我们看得很清楚哦,没有变化的。


再说一个我感觉很奇怪的现象:

点击(此处)折叠或打开

  1. #include <stdio.h>

  2. static int a;
  3. int b = 0;
  4. int c = 7;

  5. int
  6. main(void)
  7. {
  8.     return 0;
  9. }
这个程序与之前b未初始化的b相比,将b初始化为0。gcc 1.c -std=c89后,结果如下:

这个结果是不是和你想得不太一样呢?为什么初始化了的变量b,bss大小还是16,而不是像将b初始化为9那样大小为12?我们猜测可能是编译器默认将全局变量/静态变量(整形)初始化为0,所以我们将其初始化为0是没有达到真正的“初始化”效果的。


阅读(830) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~