本节掌握new和delete即可
简单运算频繁算:GPU
要给进程分配资源,程序运行就是处理各种数据,这些数据都是怎么存呢,局部数据,全局数据,常量数据,还有动态申请的数据,程序内存划分就分为这几个段,每个进程都会有这几个空间,



局部变量都是在栈上的,因为函数调用会建立栈贞,分区分的是生命周期,堆不去free一直在,栈出了作用域就销毁了,静态区 函数结束局部的static还在,因为放在静态区,一次性,局部, 长期局部:静态 动态申请:堆,不需要修改的:常量区的




申请空间可以对于自定义类型自动调用构造函数。内置类型没这些问题,
调用构造和析构这么重要吗:
struct ListNode
{
int val;
ListNode* next;
ListNode(int x)
:val(x)
, next(nullptr)
{}
};
int main()
{
A* p1 = new A;
A* p2 = new A(1);
delete p1;
delete p2;
ListNode* n1 = new ListNode(1);
ListNode* n2 = new ListNode(1);
ListNode* n3 = new ListNode(1);
ListNode* n4 = new ListNode(1);
n1->next = n2;
n2->next = n3;
n3->next = n4;
return 0;
}
链表就构造出来了,delete可以自动调用析构函数。
有默认构造前提下,

如果没有默认构造呢,
第一个不支持了,
半缺省的可以传一个参数,可以传两个参数,
这时候有些烦,调用的是拷贝构造,第二种写法直接用匿名对象:
构造加拷贝构造,编译器直接优化成构造,第三种写法:单参数构造函数支持隐式类型转换,多参数也支持和上面是一样的,编译器优化也是直接构造
那么我们就不会用第一种初始化,在此可以感受到默认构造的重要性。
malloc ListNode不会调用构造函数,以后都用new delete ,以前malloc要检查NULL,现在为什么不检查:new 失败了是抛异常,平时失败不了,内存足够大
此时就出错了
/// 1M Լ 100wByte
// 1G Լ 10Byte
int main()
{
try
{
// throw try/catch
void* p1 = new char[1024 * 1024 * 1024];
cout << p1 << endl;
void* p2 = new char[1024 * 1024 * 1024];
cout << p2 << endl;
void* p3 = new char[1024 * 1024 * 1024];
cout << p3 << endl;
}
catch (const exception& e)
{
cout << e.what() << endl;
}
return 0;
}
what就是捕获了什么跟我说一下
这就表明申请内存失败了
捕获异常还可以这么写:

异常了直接跳到catch,
看一下能申请多大内存空间
2048才是2G

用到时候才把虚拟内存映射到物理内存
所以栈容易溢出,大数组或递归深度太深,栈溢出
new 和delete底层调用的就是malloc和free
operator new operator delete 是系统写的两个底层函数 
malloc失败出现抛异常 operator delete 内有

malloc是new的一个组成部分,内置类型new直接调用operator new,自定义类型,new 调用operator new operator new 调用malloc 申请空间成功后调用构造函数,完成初始化,
编译器对这些编译,new又不是一个函数调用,那他怎么转换成operator new 和这个东西,编译时候直接生成这个指令





这没有内存泄漏,内置类型没有调用构造函数的概念,这开空间调的是operator new,这如果用delete调用谁,operator delete 调用freedbg,我的free也调用freedbg,没有内存泄漏,
但不要写delete

这样好像没什么问题,但这时候相比于delete少调了析构

假如析构函数内有一些delete指针,析构函数没调到,那不是有内存泄露了,
如果A析构没干什么还好,free崩是没蹦但是有内存泄漏风险

这样去写也不会有内存泄露,new[]调用operator new【】调用了operator new调用malloc,实际空间最终还是malloc,,delete是operator deletor【】调用了operator delete调用free, 所以空间不涉及构造和析构还是malloc和free
A和B都是自定义类型为什么第一段没有崩溃,第二段崩溃了。,内存对齐,A B 是一样大的,都是8字节
B是80字节,少调析构不会报错,终止程序的错误一般都是内存错误
10个A对象是84字节, 
P3指向位置不对,前面还有多开的空间,没有释放,B不开这四个字节因为编译器给优化了,因为编译器看到B没写析构函数,也就是说这个个数给delete【】用,我不知道调用多少个析构函数,所以p3往前偏移四个字节取到个数,b由于没写析构编译器检查了一下,没什么资源要释放,自动生成的析构也不需要做什么事情,所以编译器一步到底就不调析构函数了,也就不需要多余空间了,p3有问题的原因是,deletep3 不存在头上申请个数这样的问题那我就调用一次析构,把这个对象析构了最后operator delete调到free是从这个地方释放的
但是空间是从前面申请的,所以如果B这里把析构写上,编译器优化就没有了,也会崩溃
记住结论即可
new底层就是调operator new 和构造函数为什么调operator new:直接调malloc会抛异常,new是加强版malloc.

被折叠的 条评论
为什么被折叠?



