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;
- }