C++内存管理
内存分区
- 栈区:
- 堆区:由new/malloc分配的内存块,不归编译器管,需要程序员手动释放(程序结束后会自动被操作系统回收)
- 全局/静态变量区:静态变量(局部static变量和全局static变量)、全局变量和常量
- 常量区:常量字符串,不允许修改
- 代码区:函数体
类的内存存储
- 类中非静态成员的大小之和
- 编译器加入的额外成员变量(如指向虚函数表的指针)
- 内存对齐所加的padding
注:所有的函数都是放在代码区的,包括静态函数
空类的大小是0吗?
空类的大小不为0,编译器不允许空类的大小为0,具体大小由编译器定,如vs设置空类大小为1
#include <iostream>
using namespace std;
class A {
};
int main() {
A a;
cout << "sizeof A:" << sizeof(A) << endl;
cout << "sizeof a:" << sizeof(a) << endl;
}
/*结果
sizeof A:1
sizeof a:1
*/
带有虚函数的空类大小不为0,因为有虚函数指针的存在
#include <iostream>
using namespace std;
class A {
virtual void show(){}
};
int main() {
A a;
cout << "sizeof A:" << sizeof(A) << endl;
cout << "sizeof a:" << sizeof(a) << endl;
}
/*结果
sizeof A:8
sizeof a:8
*/
new的三种用法
1. plain new
申请失败抛出std::bad_alloc异常
2. nothrow new
不抛出异常,如果失败侧返回NULL
char* p = new(nothrow) char[10e11];
if(p == NULL)
{
cout << "alloc failed" << endl;
}
delete p;
3. placement new
不申请内存,用于将已经分配成功的内存重新构造成新的对象或对象数组。
int* p = new int[4];
string str = new(p) string;
内存池
this指针的用法
- this指针是类的指针,指向对象的首地址
- this指针只能在成员函数中使用,在全局函数、静态函数中都不能使用
- this指针只有在成员函数中才有定义,且存储位置会因编译器不同有不同存储位置
delete this的后果
在类对象的内存空间中,只有数据成员和虚函数表指针,并不包含代码内容,类的成员函数单独放在代码段中。在调用成员函数时,隐含传递一盒this指针,让成员函数知道当前是哪个对象在调用它。当调用delete this时,类对象的内存空间被释放。在delete this之后进行的其他任何函数调用,只要不涉及到this指针的内容,都能够正常运行。一旦涉及到this指针,如操作数据成员,调用虚函数等,就会出现不可预期的问题(虽然delete this释放了类空间的内存空间,但是内存孔家吗却并不是马上被回收到系统中,可能由于缓冲或者其他原因,导致这段内存空间暂时并没有被系统收回,此时这段内存是可以访问的)。
this指针的生命周期:成员函数的开始执行前构造,在成员的执行结束后清除
存放地址:this指针会因编译器不同而有不同的放置位置。可能是栈,也可能是寄存器,甚至全局变量。
this是如何传递类中的函数的?
成员函数也是存储在代码区,每次调用对应对象的成员函数,都会在该函数的参数中添加this指针。
this指针首先入栈,然后成员函数的参数从右向左进行入栈,最后函数返回地址入栈。

浙公网安备 33010602011771号