【问题标题】:What happens when I clear a vector of struct?当我清除一个结构向量时会发生什么?
【发布时间】:2020-05-19 11:48:08
【问题描述】:

这里有内存管理问题。

我得到一个结构体Test1vector,这个结构体包含一个map。在我的程序中,函数将在本地创建 Test1s,并使用本地创建的地图。

考虑以下代码:

#include <map>
#include <vector>

struct Vec3 {
    float x, y, z;
};

struct Test1 {
    int64_t a;
    std::map<int, Vec3> mapy;
};

std::vector<Test1> global;

void ClearGlobal() {
    global.clear();
}

void AddToGlobal() {
    Vec3 test = { 1, 2, 3 };
    std::map<int, Vec3> mapy;
    mapy[1] = test;
    global.push_back({ 10, mapy });
}

void main() {
    AddToGlobal();
    ClearGlobal();
}

我想知道当我清除那个向量时会发生什么?所有的结构也会从内存中释放出来吗?

【问题讨论】:

  • 是的,每个Test1 及其成员都将被销毁。您的 global 向量的大小将设置为 0,但容量将与以前相同。
  • 如果你想测试它,你可以编写一个析构函数~Vec3(),它会打印一条诊断消息。
  • 这取决于你所说的从记忆中解放出来是什么意思。向量(其缓冲区)使用的内存本身不会被释放,只会破坏对象(元素)。这种破坏也会破坏内部映射,这将释放它们动态分配的任何内存。

标签: c++ vector memory-management stdmap


【解决方案1】:

我想知道当我清除那个向量时会发生什么?

根据文档,元素被删除。

所有结构也会从内存中释放出来吗?

向量的容量不变。

【讨论】:

    【解决方案2】:

    简短回答Test1mapy 字段的内存将被释放,但结构本身的内存仍然存在。

    长答案

    清除向量会调用向量内对象的析构函数,但不会释放对象。这是来自cppreference的sn-p:

    保持向量的容量()不变

    这意味着capacity() 大小为sizeof(Test1) 的元素不会被释放。但是由于调用了析构函数,所以mapy等内部字段就被销毁了。由于mapy 在堆上拥有一些内存,它的销毁会释放该内存。因此,所有指向Test1 之外的堆的Test1 内存都被释放。

    请注意,这种释放只是由于内部字段的析构函数而发生的。如果您的结构包含指向内存块的原始指针,并且如果Test1::~Test1 没有明确删除它,则在调用clear() 后不会释放该内存块。这可能会导致内存泄漏。

    编辑:看到另一个答案,我想强调的是,在clear() 之后,没有任何元素是有效的,即使没有一个元素被释放。除了通过重新创建向量中的元素的方法(例如push_backemplace_backresizeinsert)之外,您不应该读取或写入它们。在调用 clear() 之后对元素的任何其他访问都是未定义的行为,这可能导致奇怪和不可预测的程序行为(主要是由于打破了代码不依赖于未定义行为的假设而使编译器混淆)。永远不要依赖未定义的行为。永远不要故意调用未定义的行为,即使“今天似乎有效”。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多