C++中不同类型对象的存放位置

在C++中,定义的对象被放在不同的区域中,以下就各个区域以及不同类型对象的存储情况作简要介绍。

1. 存储区域

栈(Stack)是存在于作用域(scope)的一块内存空间。
例如当你调用函数时,函数本身就会形成一个栈用来放置它所接收的参数,以及返回地址。
堆(Heap 或 system heap)是指由操作系统提供的一块内存空间。
程序可以从其中动态分配获得若干区块。
全局存储区(静态存储区)是操作系统提供的一块内存区间。

2. 不同类型对象的存储

下面先给出一段代码:

class A{
public:
	A(){ cout << "A的构造函数" << endl; }
	~A(){ cout << "A的析构函数" << endl; }
};
class B{
public:
	B(){ cout << "B的构造函数" << endl; }
	~B(){ cout << "B的析构函数" << endl; }
};
class C{
public:
	C(){ cout << "C的构造函数" << endl; }
	~C(){ cout << "C的析构函数" << endl; }
};
class D{
public:
	D(){ cout << "D的构造函数" << endl; }
	~D(){ cout << "D的析构函数" << endl; }
};
void fun(){
	B b;  //局部对象
	static C c;  //静态局部对象
	D *d = new D;  //动态对象
	delete d;
	cout << "程序结束" << endl;
}
A a;  //全局对象
int main(){
	fun();
	cout << "主程序结束" << endl;
	return 0;
}

输出结果如下:
输出结果

2.1 全局对象

全局对象(global object),其生命在程序结束之时才结束。
全局对象和静态局部对象存放在全局存储区(静态存储区),初始化的全局对象和静态局部对象在一块区域, 未初始化的全局对象和未初始化的静态局部对象在相邻的另一块区域。程序结束后由系统释放。
程序中的 a 就是一个全局对象,可以看出,程序开始时,它最先被构造,而当整个程序结束之际才被析构。

2.2 局部对象

局部对象(stack object 或 auto object),其生命在作用域结束时结束,它的析构函数会自动被调用,即对象自动被清理。
很显然,局部对象存放在栈中。
程序中的 b 就是一个局部对象,在 fun() 函数中被构造,在 fun() 函数结束的时候被析构。

2.3 静态局部对象

静态局部对象(static local object),其生命在作用域结束之后仍然存在,即此时对象的析构函数并不会被调用,直到整个程序结束。
程序中的 c 就是一个静态局部对象,在 fun() 函数中被构造,而当整个程序结束之际才被析构。

2.4 动态对象

动态对象(heap object),其生命在它被 delete 之际结束。
动态对象存放在堆中,而用于创建动态对象的指针存放在栈中。
程序中的指针 d 就是用来创建动态对象的,在 new 的时候被构造,而在 delete 的时候被析构。
注:new 的对象,必须使用 delete 去显式的调用析构函数,否则程序不会去调用其析构函数,从而造成内存泄露。内存泄漏的原因是,在 fun() 函数中被动态构造的指针 d ,在 fun() 函数结束时刻结束生命,而其指向的空间并没有被释放,这块内存很可能失去了程序的控制,程序结束之后被交还给操作系统。

猜你喜欢

转载自blog.csdn.net/qq_35481167/article/details/83823511