通过迭代器清除内存时,会发生异常。
#include <stdint.h>
#include <vector>
#include "Shared.h"
using namespace std;
const int RangeItems = 3;
struct Anchor
{
uint16_t anchor_addr;
float range[RangeItems];
float dbm;
Anchor(uint16_t addr) : anchor_addr(addr), dbm(0) {}
};
struct Link
{
vector<Anchor> Anchors;
Link()
{
Anchors.reserve(10); //зарезервировать сразу N элементов
}
};
struct Link* init_link(uint16_t addr)
{
Link* l = new Link();
Anchor* a = new Anchor(addr);
l->Anchors.push_back(*a);
return l;
}
void add_To_End(struct Link* p, uint16_t addr)
{
Anchor* a = new Anchor(addr);
p->Anchors.push_back(*a);
}
Result delete_Anchor(Link* p, uint16_t addr)
{
for (auto it = p->Anchors.begin(); it != p->Anchors.end(); ++it)
{
Anchor a = *it;
if (a.anchor_addr == addr)
{
p->Anchors.erase(it);
delete &a; //ECXEPTION!!!!!
return Succsess;
}
}
return NotFound;
}
用向量测试
int main()
{
uwb_data= init_link(1);
add_To_End(uwb_data, 2);
add_To_End(uwb_data, 3);
add_To_End(uwb_data, 4);
auto res = delete_Anchor(uwb_data, 3);
}
当从vector中移除一个元素时,我想清除Anchor元素占用的内存,但是出现Exception。
与所有标准容器一样,向量会保留您放入其中的任何内容的副本。
那些。这里:
对象的副本进入向量,即
delete你不需要在它上面调用它,你需要在原版上做它,在a. 你没有,这就是为什么这里有内存泄漏。这也是崩溃的原因 - 您
delete不是在调用您在堆上创建的对象,而是调用向量创建的副本。通常,在现代 C++ 中,您几乎不需要使用
new,delete除非您制作自己的矢量版本或类似的东西。添加这样的元素是正确的:
.emplace_back(addr);或者.push_back(Anchor(addr));(它也适用于您的课程.push_back(addr);)。delete当不需要删除时,就足够了erase。Link创建 via 也是没有意义的new。简直了Link l; ... return l;。然而,由于您是用 C ++ 而不是 C 编写的,因此struct Link只需简单地编写就足够了Link(除了结构定义本身之外的所有地方)。这就是发生的事情:
init_link(1);创建Link和 ,然后将副本放入为该对象分配内存的对象向量 中。AnchorXL1XA1AnchorLinkYA1接下来,_调用 使用地址
add_To_End(uwb_data, 2);创建并将副本放入(下对象的 )向量中,该向量为该对象分配内存。(向量中已经有两个这样的对象)AnchorXA2Anchoruwb_dataYA2调用:
delete_Anchor(uwb_data, 1)找到uwb_data->Anchors两个相似的对象并删除它们。因此,向量释放内存YA1并YA2有很多解决方案:
Anchor在空闲内存中创建,而只是将其移动到向量中Anchors.emplace_back(Anchor(1))(这种方式可能更好)push_back(*a)释放内存а之后(毕竟,无论如何都不再需要该对象,因为向量中有它的副本)