std:vector、std:shared_ptr可存放在栈区或者堆区,但其vector中的元素、std:shared_ptr托管的对象存在堆区!

文章讨论了C++中std::vector作为动态数组容器如何在运行时管理内存,以及元素存储在堆区的情况。同时,介绍了std::shared_ptr作为智能指针如何在栈区或堆区存储,以及始终指向堆区内存的特点,强调了它们在内存管理和性能优化中的作用。
摘要由CSDN通过智能技术生成

在 C++ 中,std::vector 是一种动态数组容器,它可以在运行时动态地分配和管理内存。std::vector 存储的元素通常是连续分配的,并且可以根据需要动态地调整其大小。因此,std::vector 中的元素存储在堆区内存。

当我们创建一个 std::vector 对象时,它会在堆区分配一段连续的内存空间,用于存储其元素。这段内存空间的大小取决于 std::vector 对象的大小和元素数量。在向 std::vector 中添加元素时,如果当前的内存空间不足以容纳新元素,std::vector 会自动分配更大的内存空间,将原有的元素拷贝到新的内存空间中,并释放原有的内存空间。(可能会有 迭代器失效的问题)

需要注意的是,std::vector 对象本身可以存储在栈区或堆区。如果我们使用 new 运算符动态分配一个 std::vector 对象,它将存储在堆区。例如:

std::vector<int>* vec = new std::vector<int>(); // 存储在堆区

// 如果我们将 std::vector 对象定义为一个局部变量或全局变量,则它将存储在栈区。例如:
void foo(){
    std::vector<int> vec; // 存储在栈区
}

std::vector<int> global_vec; // 存储在栈区

无论 std::vector 存储在栈区还是堆区,其元素始终存储在堆区内存中。因此,我们可以将 std::vector 作为参数传递给函数,而不会担心复制大量数据的性能问题。

这个有点类似与智能指针,智能指针对象本身是可以存在在栈区或者堆区的,用于管理动态分配的内存,因此它需要存储在堆区。

std::shared_ptr 对象本身可以存在于堆区或栈区,这取决于它是如何创建的。

如果我们使用 new 运算符来创建一个 std::shared_ptr 对象,它将存储在堆区。例如:

std::shared_ptr<int>* ptr = new std::shared_ptr<int>(newint(42)); // ptr 存在于堆区,指向的内存块也存在于堆区

在这个例子中,ptr 存储在堆区,它指向的内存块也存储在堆区。

如果我们将 std::shared_ptr 对象定义为一个局部变量或全局变量,它将存储在栈区。例如:

void foo(){
    std::shared_ptr<int> ptr(newint(42)); // ptr 存在于栈区,指向的内存块存在于堆区
}

std::shared_ptr<int> global_ptr(newint(42)); // global_ptr 存在于栈区,指向的内存块存在于堆区

在这个例子中,ptrglobal_ptr 存储在栈区,它们指向的内存块存储在堆区。

需要注意的是,无论 std::shared_ptr 存储在堆区还是栈区,它所指向的内存块始终存储在堆区。这是因为 std::shared_ptr 是用于管理动态分配的内存的智能指针,它需要存储在堆区,以便进行引用计数和自动释放内存。

而且引用计数也是存放在堆区的,使用make_shared去创建智能指针的时候,引用计数位于分配的对象前面4B的位置。

当我们使用 std::make_shared 创建一个智能指针对象时,内存分配和对象构造都是在同一块连续的内存中完成的。这种内存布局称为“控制块”,它存储了引用计数、指向堆区内存的指针以及其他辅助信息。因此,通过 std::make_shared 创建的对象是一个连续的内存块,其中智能指针对象本身存储在控制块中。

void foo(){
    auto ptr = std::make_shared<int>(42); // ptr 存在于栈区,指向的内存块存在于堆区
}

std::shared_ptr<int> global_ptr = std::make_shared<int>(42); // global_ptr 存在于栈区,指向的内存块存在于堆区

在这个例子中,ptrglobal_ptr 存储在栈区,它们指向的内存块存储在堆区。

需要注意的是,无论 std::shared_ptr 存储在堆区还是栈区,它所指向的内存块始终存储在堆区。这是因为 std::shared_ptr 是用于管理动态分配的内存的智能指针,它需要存储在堆区,以便进行引用计数和自动释放内存。所以 std::make_shared 函数返回的 std::shared_ptr 对象实际上是一个包含了指向堆区内存的智能指针对象。

总的来说,其实我们使用智能指针就是想用一个栈对象去托管资源,这样当栈对象被自动析构的时候就会去释放它所托管的资源,这部分大家可以参考RAII智能指针雏形。

如果有帮到你,就点个赞吧~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值