1、malloc/free和new/delete之间关系和差异。
C通过malloc/free来管理动态内存,而C++通过new/delete管理动态内存。
malloc/free的使用方法与new/delete有所不同。
malloc/free:
-
int main()
-
{
-
int *p=(int *)malloc(sizeof(int));
-
-
free p;
-
return 0;
-
}
malloc的函数原型为void *malloc(size_t size)
new/delete:
-
int main()
-
{
-
int *p=new int;
-
-
delete p;
-
return 0;
-
}
new没有函数原型,因为new和delete都是C++中的关键字
总结它们之间的关联与区别:
(1)它们都是用来管理动态内存的。
(2)new/delete,malloc/free都要成对出现,否则会造成内存泄漏的问题。
(3)malloc函数在使用时需要指定开辟空间大小,而且因为malloc函数返回值是void*,所以需要强制转换。
而new则会自己及计算空间大小,返回对应类型指针。
(4)malloc/free只负责开辟空间释放空间,而new/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理(清理
成员)。
(5)malloc/free是C的库函数,而new/delete是C++的关键字。
2、剖析new/delete、new[]/delete[]到底做了些什么事情。
在C++中,new/delete开辟对象空间,new[]/delete[]开辟对象数组空间。
new[]的方括号中是数组中对象的个数(N),使用new[]开辟空间时,不仅要开辟N个空间,还需要在这N个空间之前开辟4个字节的空间,
用来存放N,以此来告诉编译器要调用多少次构造函数,多少次析构函数。这4个字节非常重要。
-
int main()
-
{
-
int *p1=new int; //类型
-
int *p2=new int(3); //初始化
-
int *p3=new int[3]; } //数组个数
(1)new做了两件事:
a. 调用operator new分配空间。
b. 调用构造函数初始化对象。
(2)delete也做了两件事
a. 调用析构函数清理对象
b. 调用operator delete释放空间
(3)new[N]
a. 调用operator new分配空间。
b. 调用N次构造函数分别初始化每个对象。
(4)delete[]
a. 调用N次析构函数清理对象。(思考这里怎么N是怎么来的?)
b. 调用operator delete释放空间。
我们可以用图表示出来-------

3、实现NEW_ARRAY/DELETE_ARRAY宏,模拟new[]/delete[]申请和释放数组。
通过自己编写代码实现对于对象数组的开辟空间和释放空间,代码如下:
-
#define _CRT_SECURE_NO_WARNINGS 1
-
#include<iostream>
-
using namespace std;
-
class Array
-
{
-
public:
-
Array(size_t size = 10) //数组类的构造函数
-
: _size(size)
-
, _a(0)
-
{
-
cout << "Array(size_t size)" << endl;
-
if (_size > 0)
-
{
-
_a = new int[size];
-
}
-
}
-
~Array() //析构函数
-
{
-
cout << "~Array()" << endl;
-
if (_a)
-
{
-
delete[] _a;
-
_a = 0;
-
_size = 0;
-
}
-
}
-
#define NEW_ARRAY(PTR,TYPE,N)\ //利用宏开展实现new[]
-
do \
-
{ \
-
PTR = (TYPE*)operator new(sizeof(TYPE)*N+4); \ //调用operator new函数开辟N个TYPE类型的空间,还要另外开辟4个字节空间
-
(*(int*)PTR) = N; \ //在开辟的4个字节空间中存放N,即对象个数
-
PTR = (TYPE*)((int*)PTR + 1); \ //将PTR指针后移到对象空间
-
for (size_t i = 0; i < N; ++i) \ //对对象数组空间调用构造函数
-
new(PTR + i)TYPE; \
-
}while (false); \
-
-
#define DELETE_ARRAY(PTR,TYPE)\
-
do{ \
-
size_t N = *((int*)PTR - 1); \ //在NEW_ARRAY中PTR指向对象数组,现在将4个字节处的值取出来赋给N
-
for (size_t i = 0; i < N; ++i) \ //调用析构函数释放空间
-
PTR[i].~TYPE(); \
-
PTR = (TYPE*)((char*)PTR - 4); \ //开辟的空间还有4个字节未释放,将PTR前移,调用operator delete释放
-
operator delete(PTR); \
-
} while (false);
-
private:
-
int*_a;
-
size_t _size;
-
};
-
-
int main()
-
{
-
Array*p1;
-
NEW_ARRAY(p1, Array, 10);
-
-
DELETE_ARRAY(p1, Array);
-
system("pause");
-
return 0;
-
}