当我清除一个结构向量时会发生啥?

Posted

技术标签:

【中文标题】当我清除一个结构向量时会发生啥?【英文标题】: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(),它会打印一条诊断消息。 这取决于你所说的从记忆中解放出来是什么意思。向量(其缓冲区)使用的内存本身不会被释放,只会破坏对象(元素)。这种破坏也会破坏内部映射,这将释放它们动态分配的任何内存。 【参考方案1】:

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

根据文档,元素被删除。

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

向量的容量不变。

【讨论】:

【参考方案2】:

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

长答案

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

保持向量的容量()不变

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

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

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

【讨论】:

以上是关于当我清除一个结构向量时会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章

当我从 c 中的一个分叉的孩子执行()时会发生啥

当我以下列方式修改熊猫数据框时会发生啥

当一个线程 execve() 一个文件时会发生啥?

当我用尽 bigint 生成的密钥时会发生啥?如何处理?

当我用尽 bigint 生成的密钥时会发生啥?如何处理?

存储结构向量