您的位置:首页 > 其它

关于内存的分配

2007-11-22 19:10 211 查看
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一个对象,只声明一个对象,或者这个对象生存期过的时候,也可能会出错的。对于这种错误比较难查找。

我通常会建议不要在构造函数和析构函数中做具体的事情,一般只做指针的置空等操作。我通常会将初始化函数和回收函数,显示的写成两个函数,显式的调用。因为如果你在构造函数或者析构中出现了错误,那么系统对于这个对象的回收是困难的,因为这个对象可能没有完全建立或者无法回收。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: