关于内存的分配

C++程序的编译运行,其实大致可以将内存分为四个部分。

1。heap(堆),用得最多的就是这个区域了,由程序主动发起分配,必须由程序主动释放 ,当然进程都关了,系统也就回收了。

2。stack(栈),和上面这个单词比较容易混,中文翻译出来是一样,为了区别就不用中文了。这个是由系统主动的为一个线程分布的,每个线程2M。无需主动申请,变量定义时,系统分配,变量的生存期过了,系统负责回收。真因为这样,所以2M一直够用。

3。静态变量区,这个是static变量的天下,优先所有的变量初始化,最后释放的空间,系统负责回收。

4。代码段,这是函数存放的地方,程序无非就是内存的操作,函数就是控制过程。前三个认为是数据段,这个是代码段。

至于有人说常量在一个独特的区,这个在不同的系统中说法不一,暂时认为它也在stack里。

class A

{

public:

int i;

}

class B

{

public:

int j;
int func(int& i)

{

i =9;

return 1;

}

}

可以看看sizeof(A),sizeof(B)的大小是一样的,因为多一个函数并不占用数据段。

在程序中声明 int i=10;系统会在stack中分配一个整数的空间。当i的生存期完结时,系统自动回收。变量的生存期就是一个大括号而已。对于这个特性,可以有一个小的技巧,在线程锁的使用中比较实用,可以有效地避免死锁。

int func(int i)

{

{

   Lock tmp(*tmp1)               //tmp1为成员变量,是一把系统的锁,tmp为自己写的一个类Lock的类对象,它的

   if(i==j)                                 //Lock的构造函数调用tmp1的锁事件,析构函数调用tmp1的解锁事件。这样子可以

  {                                           //有效的防止死锁。因为在加锁zhiho,该函数如果出现异常退出,或者函数return时

     int b = 0;                        //没有解锁,将会死锁,那么利用生存期,交给系统来自动执行其析构函数,解锁。无

  }                                         //论任何的异常跳出,都会过了tmp的生存期,系统调用其析构,于是自动地解锁--算

}                                           //一个技巧吧。

int b = 2;

}

如果new出来和malloc出来的内存,划分自heap里面,系统不会知道什么时候使用完成,需要程序显式的调用delete和free来进行释放的。

new和malloc的区别,new会触发构造函数,因为要明确new出来的类型,malloc直接操作heap的空间而已,并没有指明这个空间的用途。构造函数和析构函数会在一个类对象的调用的时候自动地触发。所以当一个类的构造或者析构函数有问题的时候,不需要new一个对象,只声明一个对象,或者这个对象生存期过的时候,也可能会出错的。对于这种错误比较难查找。

我通常会建议不要在构造函数和析构函数中做具体的事情,一般只做指针的置空等操作。我通常会将初始化函数和回收函数,显示的写成两个函数,显式的调用。因为如果你在构造函数或者析构中出现了错误,那么系统对于这个对象的回收是困难的,因为这个对象可能没有完全建立或者无法回收。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值