1
malloc开辟空间的问题:
1) 程序员必须确定对象的长度。
2) malloc返回一个void*指针,c++不允许将void*赋值给其他任何指针,必须强转。
3) malloc可能申请内存失败,所以必须判断返回值来确保内存分配成功。
4) 用户在使用对象之前必须记住对他初始化,需要另外手动显示调用构造函数进行初始化,用户有可能忘记调用初始化函数。
2
// malloc不会调用构造函数 而new会调用构造函数
// free 不会调用析构函数 delete会调用析构函数
3
// malloc和free配套使用 ,他们都属于库函数
// new 和 delete 配套使用 ,他们属于运算符
4
// malloc返回的是void* 需要强制类型转换 ,而new返回是该对象的指针,不需要类型转换
5
不要用void* 接受 new出来的对象,原因是无法进行释放
利用new创建数组 delete时候 要加【】 delete [] 数组名
6使用new和delete在堆上创建数组非常容易。
//创建字符数组
char* pStr = new char[100];
//创建整型数组
int* pArr1 = new int[100];
//创建整型数组并初始化
int* pArr2 = new int[10]{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//释放数组内存
delete[] pStr;
delete[] pArr1;
delete[] pArr2;
7当创建一个对象数组的时候,必须对数组中的每一个对象调用构造函数,除了在栈上可以聚合初始化,必须提供一个默认的构造函数。
class Person{
public:
Person(){
pName = (char*)malloc(strlen("undefined") + 1);
strcpy(pName, "undefined");
mAge = 0;
}
Person(char* name, int age){
pName = (char*)malloc(sizeof(name));
strcpy(pName, name);
mAge = age;
}
~Person(){
if (pName != NULL){
delete pName;
}
}
public:
char* pName;
int mAge;
};
void test(){
//栈聚合初始化
Person person[] = { Person("john", 20), Person("Smith", 22) };
cout << person[1].pName << endl;
//创建堆上对象数组必须提供构造函数
Person* workers = new Person[20];
}
8
当我们使用一个delete的时候,我们必须让delete知道指针指向的内存空间中是否存在一个“数组大小记录”的办法就是我们告诉它。当我们使用delete[],那么delete就知道是一个对象数组,从而清楚应该调用几次析构函数。
结论:如果在new表达式中使用[],必须在相应的delete表达式中也使用[].如果在new表达式中不使用[], 一定不要在相应的delete表达式中使用[].