//所谓stack(栈),所谓heap(堆)
Stack,是存在于某作用域(scope)的一个内存空间(memory space)。例如当你调用函数,函数本身即会形成一个stack用来放置它所接受的参数
,以及返回地址。
在函数本体(function body)内声明的任何变量,其所使用的内存都取自上述stack。
Heap,或叫system heap,是指拥由操作系统提供的一个global内存空间,程序可动态分配(dynamic allocated)从其中获得若干区块(blocks)。
class Complex{....};
function()
{
Complex c1(1, 2);
Complex* p = new Complex(3);
}
//c1所占用的空间来自stack,在函数调用结束后会自动销毁,但p的内存是通过new在heap中获得的,在函数调用结束后是不会自动销毁的,只能通过 delet手动销毁
//c1是所谓的stack object,其生命在作用域(scope)结束之后结束。这种作用域内的object,又称为auto object,因为它会被[自动]清除,就是析构函数会自动被调用。
//static local objects的生命期
class Complex{...};
function()
{
static Complex c2(1, 2);
}
//c2便是所谓的static object,其生命在作用域(scope)结束时候仍然存在,直到整个程序结束。即析构函数在程序结束后才调用
//flobal objects的生命期
class Complex{...};
...
Complex c3(1, 2);
int main()
{
...
}
//c3便是所谓的global object,其生命期在整个程序结束之后才结束。你也可以把她视为一个static object,其作用域是[整个程序]
//heap objects的生命期
class Complex{...};
...
function()
{
Complex* p = new Complex;
...
delete p;
}
//p所指的便是heap object,其生命期在它被deleted之际结束。
class Complex{...};
...
function()
{
Complex* p = mew Complex;
}
//以上出现内存泄漏(memory leak),因为当作用域结束,p所指的heap object仍然存在,但指针p的生命却结束了,作用域之外再也看不到p(也就没有delete p)
//new:先分配memory,再调用构造函数
1.分配内存。
2.把内存转化为相应的数据类型。
3.给这块内存赋值
//delete:先调用析构函数,再释放memory(以String类为例)
1.调用析构函数,销毁动态分配的字符串的内存。
2.释放String类的memory,销毁String类内的字符串指针
//在String类中的构造函数和析构函数中,我们使用了new char[strlen(cstr)+1]和delete[],这两个函数教array new和array delete
//array new要搭配array delete
//eg: String* p = new String[3];
delete p;
//这么写,只调用了一次析构函数,即new出来的三个指针的内存被回收了,但是第二个,第三个指针指向的那两块内存却泄露了
//不过话说回来,比如Complex类,用*p = new Complex[3]和delete p是不存在内存泄露的,但我们最好不要那样写