1.堆(Heap)与栈(Stack)
由普通方式新建出来的对象属于stack object,利用new方式创建出来的对象属于heap object。它们的区别在于不同的生命周期。
简单来说就是栈对象的声明周期是当前所在的作用域(Scope),超出这个作用域就会被回收。
堆对象生命周期是整个函数,直到结束。
注意在代码中使用new
创建出来的对象,在程序结束时都应该手动delete
,否则就有可能造成内存泄漏出错。
而且形式要对应,如new char[]
,那么对应是delete []
。new
数组,删数组,new
对象,删对象。否则形式不对应也会造成内存泄露。
2.new
和delete
的解析
new
的操作是先分配内存,再调用构造函数。
整个new的操作可以理解为三个操作,分别是:分配内存、指针转型、调用构造函数。
这里对指针转型的命令static_cast
在前面也提到过,用于对指针类型进行转换。
delete
的操作是先调用析构函数,再释放内存。
字符串本身只是一个指针而已。
3.动态分配内存块
每一小格代表4个字节。在调试模式下,编译器会自动在前面增加32个字节,后面增加4个字节(灰色部分)。 并且在首位还各有一个4字节的cookie(棕色部分)。当这些添加完成后,看其是否是16的倍数,如果不是就补充成16的整数倍(绿色部分)。 而Release模式下就没有灰色部分。只有它本身+cookie+填充部分(如果需要的话)。 从这角度也可以看出来,Debug模式要比Release更加消耗内存。 对于数组而言,也与对象类似。 不同的是在VC中,会在数组的头部用一个整数(4字节)来记录数组长度。 如果array new没有搭配array delete,那么发生内存泄漏的,不是本身数组的这一部分内存。 而是数组中每个元素的指针所指向的那块内存。 例如一个string数组,如果用delete,那么会造成后续字符串指向的那块内存空间泄漏,没有指针再指向它们了,不受控制了。 当然如果说数组元素中没有指针,用delete也不会造成内存泄漏。 但是从养成一个好习惯的角度考虑,写代码要尽量严谨。 因此只要是对于数组,即使数组元素没有指针,也建议用array delete。
4.C++智能指针学习
智能指针共分为4种,即auto_ptr
、unique_ptr
、shared_ptr
、weak_ptr
。
智能指针的作用是管理一个指针,因为存在以下这种情况:申请的空间在函数结束时忘记释放,造成内存泄漏。
所以智能指针的作用原理就是在函数结束时自动释放内存空间,不需要手动释放内存空间。
智能指针都在头文件memory.h
中。
这里重点学习一下shared_ptr
。
shared_ptr
是智能指针(smart pointer)的一种,作用如同指针,但会记录有多少个shared_ptrs共同指向一个对象。
这便是所谓的引用计数(reference counting)。一旦最后一个这样的指针被销毁,也就是一旦某个对象的引用计数变为0,这个对象会被自动删除。
这在非环形数据结构中防止资源泄露很有帮助。使得指针可以共享对象,并且不用考虑内存泄漏问题。
shared_ptr
可以支持普通指针的所有操作,完全可以像操作普通指针一样操作智能指针。
可以通过三种方式得到:
- 1.通过一个指向堆上申请的空间的指针初始化(切记不要用栈上的指针,否则,当智能指针全部释放控制权(栈中的对象离开作用域本身就会析构一次),将会析构对象,导致出错)
- 2.通过make_shared函数得到
- 3.通过另外一个智能指针初始化
下面这段代码简单演示了shared_ptr
的使用。
#include <memory>
#include <iostream>
int main()
{
int *p = new int(30);
std::shared_ptr<int> bptr(p);//方式1
std::shared_ptr<int> aptr = std::make_shared<int>(20);//方式2
std::shared_ptr<int> cptr(aptr);//方式3
std::cout << "aptr.use_count() = " << aptr.use_count() <<" value = "<<*aptr<<std::endl;//use_count 是引用计数器
std::cout << "bptr.use_count() = " << bptr.use_count() <<" value = "<<*bptr<<std::endl;
std::cout << "cptr.use_count() = " << cptr.use_count() <<" value = "<<*cptr<<std::endl;
}
运行结果如下:
5.参考资料
- https://blog.csdn.net/zy19940906/article/details/50470087
- https://blog.csdn.net/zy19940906/article/details/50481969
- https://blog.csdn.net/man_sion/article/details/77196766
- https://www.cnblogs.com/lanxuezaipiao/p/4132096.html
本文作者原创,未经许可不得转载,谢谢配合