C与C++的内存机制的比较

C语言与C++内存非常相似,这也是我一直搞不清楚他的原因;下面梳理一下他们之间的区别:

  1、先说C语言的内存机制

    • 栈        位于函数内的局部变量(包括函数实参),由编译器负责分配和释放,函数结束,栈变量失效;

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

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

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

    • 程序代码区         存放程序二进制代码的区域。


  2、再说C++的内存机制

    • 栈        位于函数内的局部变量(包括函数实参),由编译器负责分配释放,函数结束,栈变量失效。

    • 堆        这里与C不同的是,该堆是由new申请的内存,由delete负责释放。

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

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

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



下面举个栗子,比较C与C++在全局区/静态区的区别(Linux):

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
 
static  int  a;
int  b;
int  c = 1;
 
int  main( void )
{
     return  0;
}

将文件编译成可执行文件,打印文件的大小:

1.PNG

可以看到,数据段(data,不包括bss)为252,bss(未初始化数据段)为16;

接下来将测试代码进行修改(对b进行初始化):

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
 
static  int  a;
int  b = 1;
int  c = 1;
 
int  main( void )
{
     return  0;
}

将文件编译成可执行文件,打印文件的大小:

2.PNG

可以看到,数据段(data,不包括bss)为256(252+4),bss(未初始化数据段)为12(16-4);


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

接下来看一下C++运行的结果:

b未手动初始化(int b;):

3.PNG

b手动初始化为0(int b = 0):

5.PNG

上面在C++下面,数据段(data)没有变化;因此在c语言中,全局变量又分为初始化的和未初始化的,在c++里面没有这个区分了,他们共同占用同一块内存区。


但是,这里面有一个非常小的细节对于b的初始化,如果手动初始化为0以外的数字,打印出来的data段又与C语言是一样的:

b初始化为1:

8.PNG

b不初始化:

7.PNG


以上问题的出现,是什么原因,还没有查清楚。

可能的原因是:

BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。(0也算未初始化)
数据段(data segment)通常是指用来存放程序中已初始化且不为0的全局变量的一块内存区域。(只有初始化为0之外的数字才算真正的初始化)

具体原因不知道,只是猜测。



本文转自 七十七快 51CTO博客,原文链接:http://blog.51cto.com/10324228/2083826

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值