指针(一),栈和自由存储区
自由存储区:也称为堆(heap),可以看作大量的内存段。通过 new 操作符分配的内存在堆中。程序结束之前不自动清除自由存储区。需要由程序来负责释放(delete)。
栈:函数调用的时候,在栈中保存局部变量和函数参数等。当函数返回时,自动清除栈。
new 关键词:
new 进行自由存储区中内存分配。
unsigned short int* pPointer = new unsigned short int;
如果 new 不能在自由存储区中创建内存,则会返回 null 指针。每次分配新内存时一定要检查指针是否为 null.
delete 操作实际上是恢复指针所指的内存,使之可以再用,而不至于造成内存泄漏(memory leak).
而指针仍然是指针,必要时还可以重新赋值。
如果对已经释放过的指针调用 delete 操作,会导致程序崩溃。当删除指针时,给指针赋值 null(0), 对空指针调用 delete 是安全的。
内存泄漏:一种情况是程序在未释放它指向的内存之前就给指针重新赋值。例如:
unsigned short int* pPointer = new unsigned short int;
*pPointer = 72;
pPointer = new unsigned short int;
*pPoniter = 84;
*pPointer = 72;
pPointer = new unsigned short int;
*pPoniter = 84;
在自由存储区中建立对象:
// 这个是没有参数的构造函数的情况
Cat *pCat = new Cat;
Cat *pCat = new Cat;
当程序对自由存储区中的对象指针调用 delete 时,在释放内存之前会自动调用对象的析构函数。这个策略给类提供了清理的机会。例子:
#include <iostream>
using namespace std;
class SimpleCat
{
public:
SimpleCat();
~SimpleCat();
private:
int itsAge;
};
SimpleCat::SimpleCat() {
cout << "Constructor called.\n";
itsAge = 1;
}
SimpleCat::~SimpleCat() {
cout << "Destructor called.\n";
}
int main(int argc, char *argv[])
{
cout << "SimpleCat Frisky\n";
SimpleCat Frisky;
cout << "SimpleCat* pRags = new SimpleCat\n";
SimpleCat* pRags = new SimpleCat;
cout << "delete pRags\n";
delete pRags;
cout << "Exiting, watch Frisky go\n";
return 0;
}
using namespace std;
class SimpleCat
{
public:
SimpleCat();
~SimpleCat();
private:
int itsAge;
};
SimpleCat::SimpleCat() {
cout << "Constructor called.\n";
itsAge = 1;
}
SimpleCat::~SimpleCat() {
cout << "Destructor called.\n";
}
int main(int argc, char *argv[])
{
cout << "SimpleCat Frisky\n";
SimpleCat Frisky;
cout << "SimpleCat* pRags = new SimpleCat\n";
SimpleCat* pRags = new SimpleCat;
cout << "delete pRags\n";
delete pRags;
cout << "Exiting, watch Frisky go\n";
return 0;
}