(一)
先看下面的代码:
string* stringArray = new std::string[100]; ... delete stringArray;
这样的做法是错误的,因为stringArray所含的100个string对象中的99个可能并没有被适当地删除,因为它们的析构函数很可能没有被调用。
(二)
使用new时发生的事情:
(1)内存被分配出来;
(2)针对此内存会有一个或更多个构造函数被调用;
使用delete,也有两个动作:
(1)针对此内存会有一个或更多个析构函数被调用;
(2)内存被释放;
(三)
当对着一个指针使用delete,唯一能够让它知道当前是删除单一对象还是对象数组的方法就是,由你来告诉它:
std::string* stringPtr1 = new std::string; std::string* stringPtr2 = new std::string[100]; ... delete stringPtr1; delete[] stringPtr2;
(四)解决办法:
如果你调用new时,使用new[] 的形式,那么对应调用delete时也使用[],
如果你调用delete时,没有使用new[] 的形式,那么对应调用delete时也不应该使用[] 形式。
(五)
当你设计的class含有一个指针指向动态分配内存,并提供多个构造函数时,上述的规则尤为重要。
这时,你需要小心地在所有构造函数中使用相同形式的new将指针成员初始化,同时,相应的析构函数也要使用相同的形式。
(六)
当使用typedef时,要变得尤为敏感,因为你必须要明确地知道,这时的new是一个什么样的形式:
typedef std::string AddressLines[4]; // 每个人的地址有4行,每行是一个string // 这时候AddresLines是一个数组,所以new时,应该是[]形式 std:string* pal = new AddresLines; // 相当于:new string[4]; //那么,必须匹配数组形式的delete delete pal; // error,行为未定义 delete[] pal; // pass
所以,最好尽量不要对数组形式使用typedef动作。
请记住:
(1)如果在new表达式中使用[],必须在相应的delete表达式中也使用[] ;
(2)如果在new表达式中不使用[],一定不要再相应的delete表达式中使用[];
(3)尽量不要对对象数组使用typedef动作。