1.内存分布
2.c++中动态内存管理
3.operator new和operator delete函数
4.new和delete实现原理
1.内存分布
1.1常见的内存分布
1.2相关问题
答案:CCCAA AAADAB
我们讲以下易错的部分:
7.数组char2是在栈上开的空间,然后将"abcd"拷贝给该数组,所以char2指向的内容在栈上。
9.之前说过,字符串是只读数组,"abcd"是数组名,是首元素的地址,这里实际上是将字符串第一个元素的地址赋给pChar3,所以pChar3指向的内容在代码段。
补充:
猜猜看,变量a在哪?
其实,它在栈上,其实const只有限制访问的作用。
2.c++中动态内存管理
c++可以通过new和delete操作符进行动态内存管理。
new类似于malloc,delete类似于free。
2.1new和delete操作内置类型
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
int main()
{
int* pa = new int;//申请一个元素的空间
int* pb = new int(10);//单元素初始化
int* pc = new int[10];//申请10个元素的空间
int* pd = new int[10] {1, 2, 3};//多元素初始化
delete pa;//单元素释放空间
delete pb;
delete[] pc;//多元素释放空间
delete[] pd;
return 0;
}
注意:申请空间时不完全初始化,编译器会将其他元素初始化为0
注意:如果不手动初始化,编译器也不会初始化
2.2new和delete操作自定义类型
2.2.1申请一个元素的空间
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
Date()
{
cout << "Date()" << endl;
}
Date(int a)
{
cout << "Date(int a)" << endl;
}
Date(int a, int b)
{
cout << "Date(int a, int b)" << endl;
}
};
using namespace std;
int main()
{
Date* p1 = new Date;//不传参
Date* p2 = new Date(Date(1));//匿名对象传单参
Date* p3 = new Date(1);//隐式类型转换传单参
Date* p4 = new Date(Date(1, 2));//匿名对象传多参
Date* p5 = new Date(1, 2);//隐式类型转换传多参
delete p1;
delete p2;
delete p3;
delete p4;
delete p5;
return 0;
}
2.2.2申请多个元素的空间
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
Date()
{
cout << "Date()" << endl;
}
Date(int a)
{
cout << "Date(int a)" << endl;
}
Date(int a, int b)
{
cout << "Date(int a, int b)" << endl;
}
};
using namespace std;
int main()
{
Date* p1 = new Date[3];//不传参
Date* p2 = new Date[3]{ Date(1),Date(2),Date(3) };//匿名对象传单参
Date* p3 = new Date[3]{ 1,2,3 };//隐式类型转换传单参
Date* p4 = new Date[3]{ Date(1, 2),(2,3),(3,4) };//匿名对象传多参
Date* p5 = new Date[3]{ {1,2},{2,3},{3,4} };//隐式类型转换传多参
delete[] p1;
delete[] p2;
delete[] p3;
delete[] p4;
delete[] p5;
return 0;
}
那么参数个数能混传吗?
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
Date()
{
cout << "Date()" << endl;
}
Date(int a)
{
cout << "Date(int a)" << endl;
}
Date(int a, int b)
{
cout << "Date(int a, int b)" << endl;
}
};
using namespace std;
int main()
{
Date* p1 = new Date[3]{ 1,{2,3},4 };
Date* p2 = new Date[3]{ Date(1),Date(2,3),Date() };
delete[] p1;
delete[] p2;
return 0;
}
答案是可以的。
注意:new将自动调用构造函数,delete自动调用析构函数。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
Date()
{
cout << "Date()" << endl;
}
~Date()
{
cout << "~Date()" << endl;
}
};
using namespace std;
int main()
{
Date* p1 = new Date;
delete p1;
return 0;
}
但是,malloc和free不行。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
Date()
{
cout << "Date()" << endl;
}
~Date()
{
cout << "~Date()" << endl;
}
};
using namespace std;
int main()
{
Date* p1 = (Date*)malloc(sizeof(Date));
free(p1);
return 0;
}
3.operator new和operator delete函数
这是两个库函数,不是运算符重载
operator new是对malloc的封装,在operator new中,申请空间失败会抛异常。
operator delete是对free的封装,即释放空间。
4.new和delete实现原理
new等价于operator new+构造函数
delete等价于operator delete+析构函数
由于operator new申请空间失败会抛异常,所以用new开空间时,不用检查是否成功。
注意:malloc和free要配套使用,new和delete也要配套使用,它们不能混用。