C++ 释放嵌套容器和对象的内存
C++ freeing memory of nested container and objects
这个问题很有可能是重复的,但我不确定如何对此进行适当的搜索。这对你来说可能是微不足道的,但它对我这个初学者有很大帮助!
假设我有三个 classes,每个都有一个容器
class A {
std::map<int, B> container1;
};
class B {
std::unordered_map<int, C> container2;
};
class C {
std::vector<int> container3;
};
如果我有一个从 class A 创建的对象 'a',其中 container1/2/3 全部填充了数据,我的问题如下:
- 当我调用a.container1.clear()时,分配给container2和container3的内存会全部释放吗?如果是这样,C++ 是如何做到这一点的?
- 调用'a'的析构函数时,container2和3会被释放吗?
- 如果 1 和 2 为真,它们是否适用于容器的任何嵌套组合?例如这里我有 map->unordered_map->vector。不同的组合可以是 vector->unordered_map->map.
我的直觉是它们都是真的。否则,如果我有一个非常深嵌套的结构,一直到底部并显式释放那里的内存是没有意义的。
简短的回答:是的,这种情况下的所有嵌套容器都将释放内存。
长答案:让我们从头开始工作。
首先,我假设这些是结构而不是 classes(或者容器已经被声明 public);否则,a.container1.clear()
将无法编译,因为 container1 将是 a 的私有成员。但是,撇开这一点不谈:
当您调用 a.container1.clear()
时会发生什么?根据 https://www.cplusplus.com/reference/map/map/clear/,clear 方法从容器中删除所有元素,然后将其销毁。
所以,这意味着a.container1中的每个B类型的对象都将被销毁,即B的析构函数将被调用。
在 C++ 中,当 class 的对象被销毁时,class 的每个成员的析构函数在 class 的析构函数完成后被调用(在此在这种情况下,B 的析构函数是默认的编译器生成的析构函数,因为不存在用户提供的析构函数)。所以,当B被销毁后,B.container2的析构函数就会被调用。由于 container2 是一个 unordered_map,它的析构函数将销毁它包含的所有元素 (https://www.cplusplus.com/reference/unordered_map/unordered_map/~unordered_map/)
由于 container2 的元素是 C 类型的,因此 container2 中的每个 C 类型的元素都将调用其析构函数。同样,将调用 container3 的析构函数。并且,作为一个向量,container3 的存储容量将被释放,即释放 (https://www.cplusplus.com/reference/vector/vector/~vector/).
现在,我们一直走到底部,我们看到所有内存都被释放了!
这个问题很有可能是重复的,但我不确定如何对此进行适当的搜索。这对你来说可能是微不足道的,但它对我这个初学者有很大帮助!
假设我有三个 classes,每个都有一个容器
class A {
std::map<int, B> container1;
};
class B {
std::unordered_map<int, C> container2;
};
class C {
std::vector<int> container3;
};
如果我有一个从 class A 创建的对象 'a',其中 container1/2/3 全部填充了数据,我的问题如下:
- 当我调用a.container1.clear()时,分配给container2和container3的内存会全部释放吗?如果是这样,C++ 是如何做到这一点的?
- 调用'a'的析构函数时,container2和3会被释放吗?
- 如果 1 和 2 为真,它们是否适用于容器的任何嵌套组合?例如这里我有 map->unordered_map->vector。不同的组合可以是 vector->unordered_map->map.
我的直觉是它们都是真的。否则,如果我有一个非常深嵌套的结构,一直到底部并显式释放那里的内存是没有意义的。
简短的回答:是的,这种情况下的所有嵌套容器都将释放内存。
长答案:让我们从头开始工作。
首先,我假设这些是结构而不是 classes(或者容器已经被声明 public);否则,a.container1.clear()
将无法编译,因为 container1 将是 a 的私有成员。但是,撇开这一点不谈:
当您调用 a.container1.clear()
时会发生什么?根据 https://www.cplusplus.com/reference/map/map/clear/,clear 方法从容器中删除所有元素,然后将其销毁。
所以,这意味着a.container1中的每个B类型的对象都将被销毁,即B的析构函数将被调用。
在 C++ 中,当 class 的对象被销毁时,class 的每个成员的析构函数在 class 的析构函数完成后被调用(在此在这种情况下,B 的析构函数是默认的编译器生成的析构函数,因为不存在用户提供的析构函数)。所以,当B被销毁后,B.container2的析构函数就会被调用。由于 container2 是一个 unordered_map,它的析构函数将销毁它包含的所有元素 (https://www.cplusplus.com/reference/unordered_map/unordered_map/~unordered_map/)
由于 container2 的元素是 C 类型的,因此 container2 中的每个 C 类型的元素都将调用其析构函数。同样,将调用 container3 的析构函数。并且,作为一个向量,container3 的存储容量将被释放,即释放 (https://www.cplusplus.com/reference/vector/vector/~vector/).
现在,我们一直走到底部,我们看到所有内存都被释放了!