动态分配内存:
在C语言中,通过malloc函数实现动态分配内存。再通过free释放内存。
这里的内存空间特指堆区。
1、malloc需要通过指针实现。malloc函数的返回值是一个指针类型,将堆区的地址以指针的形式返回给程序员。
// nullptr是在C++中的空指针
int* ptr = nullptr;
// malloc函数之前需要指定堆空间的数据类型,要与指针的类型相对应
ptr = (int*)malloc(sizeof(int));
if(ptr == nullptr)
{
cout << "malloc error" << endl;
}
// 及时将堆空间释放,以避免造成内存泄露
free(ptr);
2、在C++中,空指针由nullptr表示,C语言里则是大写的NULL
3、在C++中,C库头文件,可以将其后面的.h删除,在前面加上c,这种命名方式为C++风格的头文件命名方式。
4.1 在C++中,动态分配内存由关键字new、和关键字delete实现。
new的作用类似于malloc。
其语法为:new + 数据类型(意味着该堆空间的大小) + 初始化的数值。
int* ptr = nullptr;
// 该堆空间类型为int,代表其大小为int类型的大小4
ptr = new int;
delete ptr;
4.2 new的后面可以跟上圆括号(),圆括号的意义为给堆空间初始化数值。
初始化的操作只有C++的new才能做到,malloc并不具备该特性。
int* ptr = nullptr;
ptr = new int(123);
cout << "*ptr:" << *ptr << endl;
delete ptr;
4.3 new的后面也可以跟上方括号[],方括号内的数值,填写的是该堆空间的大小。堆空间的大小计算方式为 数据类型大小 × []内数值的大小。在这里,new int[5] 也就意味着该堆空间的大小为 4 × 5 = 20。
int* ptr = nullptr;
ptr = new int[5]{100, 200, 300, 400, 500};
cout << "*ptr:" << *ptr << endl;
cout << "*(ptr+1):" << *(ptr+1) << endl;
cout << "*(ptr+2):" << *(ptr+2) << endl;
cout << "*(ptr+3):" << *(ptr+3) << endl;
cout << "*(ptr+4):" << *(ptr+4) << endl;
// 如果new的后面跟上了[],则delete后面业绩的跟上[]即可。
delete[] ptr;
在[]之后,也可以利用大括号{},类似给数组初始化的语句,给该连续的堆空间进行初始化。这一段初始化的数据,可以通过指针不断向后移动的方式进行访问。
总结:
new的使用,相比较于以前malloc的使用,要更加简单。并且增加了许多新的特性,例如初始化的操作。所以在C++中,会用new完全取代malloc的功能。
malloc需要通过返回的指针判断其是否为空来依此判断动态分配内存是否成功。而new则不需要判断指针,而是采取C++异常处理的方式判断动态分配内存是否成功。
如果要用new实例化对象的话,new会调用类的构造函数。delete会调用类的析构函数。如果new是由[]动态分配的连续堆空间,delete也应该加上[]。因为如果不加[]的话,delete只会调用第一次的析构函数,即只释放第一处堆空间,而不会再释放后续连续的堆空间,从而造成了内存泄漏