1. 内存分布
【说明】
-
栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
-
内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。(Linux课程重点学习)
-
堆用于程序运行时动态内存分配,堆是可以上增长的。
-
数据段--存储全局数据和静态数据。
-
代码段--可执行的代码/只读常量。
2. C++内存管理方式
a. new , delete 操作内置类型
代码举例
#include <iostream>
using namespace std;
int main()
{
int* pa = new int;
// 相当于在堆上开辟了一个 int 类型的空间
delete pa;
int* pb = new int(10);
//相当于在堆上开辟了一个 int 类型的空间并且初始化为 10
delete pb;
int* pc = new int[10];
//相当于在堆上开辟了十个 int 类型的空间
delete[] pc;
}
注意:
- 申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[]和delete[]
- 要搭配使用(如:malloc 对应 free , new 对应 delete)
b. new和delete操作自定义类型
代码举例
#include <iostream>
using namespace std;
class stack
{
public:
stack()
{
cout << "stack()" << endl;
_a = new int[10];
_top = 0;
_capacity = 10;
}
~stack()
{
cout << "~stack()" << endl;
delete _a;
}
private:
int* _a;
int _top;
int _capacity;
};
int main()
{
stack* p = new stack;
//先开辟空间,再调用构造函数
delete p;
//先调用析构函数,再销毁 p 开辟的空间
}
运行结果:
注意:
C 语言中的 malloc / realloc 对于自定义类型不会进行调用它的构造函数和析构函数
3. operator new与operator delete函数
new和delete 是用户进行动态内存申请和释放的 操作符
operator new 和operator delete 是系统提供的全局函数
new在底层调用,operator new全局函数来申请空间
delete在底层通过 ,operator delete全局函数来释放空间。
注意:
- operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;失败则会抛出bad_alloc 类型异常
- operator delete: 该函数最终是通过free来释放空间的
4. 定位new表达式(placement-new)
定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
代码举例1
#include <iostream>
using namespace std;
class stack
{
public:
stack()
{
cout << "stack()" << endl;
_a = new int[10];
_top = 0;
_capacity = 10;
}
~stack()
{
cout << "~stack()" << endl;
delete _a;
}
private:
int* _a;
int _top;
int _capacity;
};
int main()
{
stack* p = (stack *)malloc(sizeof(stack));
new(p)stack;
//调用构造函数
p->~stack();
//调用析构函数
free(p);
}
代码举例2
#include <iostream>
using namespace std;
class stack
{
public:
stack(int capcity)
{
cout << "stack()" << endl;
_a = new int[capcity];
_top = 0;
_capacity = capcity;
}
~stack()
{
cout << "~stack()" << endl;
delete _a;
}
private:
int* _a;
int _top;
int _capacity;
};
int main()
{
stack* p = (stack *)malloc(sizeof(stack));
new(p)stack(4);
p->~stack();
free(p);
}