首页 > 解决方案 > 存储在堆分配向量中的指针的免费存储空间

问题描述

我有一个unique_ptr指向已分配堆的vector指针,它本身存储指向动态分配对象的指针。问题是我认为unique_ptr释放了动态分配的向量本身,但是这个向量的析构函数不会释放动态分配的对象。那么,如何在不改变程序实现的情况下解决这个问题呢?我知道如果我使用 a我可以使用自定义析构函数来释放存储空间,但出于特定原因shared_ptr我必须坚持使用。unique_ptr

那么,向量是否可以有一个自定义析构函数shared_ptr,可以释放存储的对象?

std::unique_ptr<vector<Test*>>

标签: c++vectorheap-memoryunique-ptr

解决方案


您对类型在 C++ 中的工作方式存在误解。每种类型都有固定的大小。您可以使用sizeof. 例如,在典型平台上,avector<Test*>的大小为 24 字节。

当你在堆栈上分配一个向量时,你只是在堆栈上分配这 24 个字节。当您将对象添加到向量时,向量将从堆中分配内存来存储这些对象。

就像我说的我必须坚持这个实现,因为它比在堆栈上存储向量节省更多的堆栈内存。

它不会。所以你不必坚持这个实现。切换到一个明智的,例如std::vector<std::unique_ptr<Test>>

而且我不希望复制或移动对象以防止移动对象并保留占用更多空间的空心对象

合理的实现(例如std::vector<std::unique_ptr<Test>>)不会移动底层对象。std::vector在任何合理的平台上,移动语义已经是最佳的。

您期望移动 astd::unique_ptr与移动 a 有很大不同std::vector。您对该假设的推理是错误的,即使它是正确的,这仍然是复杂性的毫无意义的增加。

事实上,为什么不直接使用vector<Test>

看一下这个:

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> a;

    for (int i = 0; i < 10; ++i)
       a.push_back(i);

    std::cout << &a[0] << std::endl;

    std::vector<int> b = std::move(a);
    std::cout << &b[0] << std::endl;
}

输出:

0x563caf0f1f20
0x563caf0f1f20

请注意,移动向量甚至不会移动向量中的对象。它只是将对象的所有权从一个向量转移到另一个向量。

停止尝试优化已经优化的东西。


推荐阅读