[英]How to insert a struct with pointers into map?
I'm trying to insert a C struct from a third-pary library into a map.我正在尝试将来自第三方库的 C 结构插入到 map 中。 The problem is, the struct contains a pointer to other structs as a member field and when inserting this into my_map, the S2.arr field seems to be getting over written and I'm not sure why.
问题是,该结构包含一个指向其他结构的指针作为成员字段,当将其插入 my_map 时,S2.arr 字段似乎被覆盖了,我不知道为什么。
I've been able to reproduce this have have it running here.我已经能够重现它并让它在这里运行。
http://coliru.stacked-crooked.com/a/7c47a5c7c7294a49
I know the shared_ptr's may seem to confuse things, but I've left my main containers in place as it's how my larger app is accessing things.我知道 shared_ptr 可能会让人感到困惑,但我已经将我的主要容器留在原处,因为这是我的大型应用程序访问事物的方式。 Here's what I've pieced together to reproduce the problem I'm having.
这是我拼凑起来的,以重现我遇到的问题。
typedef struct {
int index;
int value;
} S1;
typedef struct {
int index;
int num;
S1 *arr;
} S2;
// populate new_vec with S1 if idx equals S1.index.
void find(int idx,
std::shared_ptr<std::vector<S1>> vec,
std::shared_ptr<std::vector<S1>> new_vec)
{
for (const auto& s1 : *vec) {
if (idx == s1.index) {
new_vec->push_back(s1);
}
}
}
int main()
{
bool found = false;
std::shared_ptr<std::vector<S1>> array;
std::shared_ptr<std::map<int, S2>> my_map = std::make_shared<std::map<int, S2>>();
std::shared_ptr<std::vector<S1>> vec = std::make_shared<std::vector<S1>>();
std::shared_ptr<std::vector<S1>> new_vec = std::make_shared<std::vector<S1>>();
// initialize vec
for (int i = 0; i < 3; ++i)
vec->push_back(S1 { 1, i});
for (int i = 0; i < 4; ++i)
vec->push_back(S1 { 2, i});
for (const auto& s1 : *vec) {
found = false;
array = std::make_shared<std::vector<S1>>();
// populate array with S1.indices that equal 1.
find(s1.index, vec, array);
my_map->insert(std::pair<int, S2>(s1.index,
S2 {
s1.index,
static_cast<int>(array->size()),
std::move(array->data())
}
));
}
for (const auto& [key, val] : *my_map) {
std::cout << "key: " << key << std::endl;
for (int i = 0; i < val.num; ++i) {
S1 s = val.arr[i];
std::cout << " index: " << s.index << ", val: " << s.value << std::endl;
}
}
}
My intention is to have this print the following:我的意图是打印以下内容:
key: 1
index: 1, val: 0
index: 1, val: 1
index: 1, val: 2
key: 2
index: 2, val: 0
index: 2, val: 1
index: 2, val: 2
index: 2, val: 3
Yet what I'm getting is this:然而我得到的是:
key: 1
index: 2, val: 0
index: 2, val: 1
index: 2, val: 2
key: 2
index: 2, val: 0
index: 2, val: 1
index: 2, val: 2
index: 2, val: 3
Update: Made some edits as maps only contain unique keys.更新:进行了一些编辑,因为地图仅包含唯一键。
array = std::make_shared<std::vector<S1>>();
On each iteration of the for
loop that has this statement, this overwrites the previous value of array
that was created on the last iteration of this for
loop.在具有此语句的
for
循环的每次迭代中,这将覆盖在此for
循环的最后一次迭代中创建的array
的先前值。
Since this is the only and the last smart pointer reference to the vector, the previous array
always gets destroyed.由于这是对向量的唯一也是最后一个智能指针引用,因此前一个
array
总是被破坏。 On each iteration of the for-loop, because this std::shared_ptr
does not wind up anywhere else, the vector created on the previous iteration of the loop will go to the big bit bucket in the sky.在 for 循环的每次迭代中,因为这个
std::shared_ptr
不会在其他任何地方结束,所以在循环的前一次迭代中创建的向量将 go 到天空中的大比特桶。
But before this happens, with each reincarnation of std::vector
, later in this for
loop we have:但在此之前,随着
std::vector
的每次转世,在这个for
循环的后面,我们有:
std::move(array->data())
Two problems here:这里有两个问题:
1) This std::move
accomplishes absolutely nothing useful whatsoever, here. 1)这个
std::move
在这里绝对没有任何用处。 But, more importantly:但是,更重要的是:
2) As you know, data()
returns an internal pointer to the vector's underlying storage. 2) 如您所知,
data()
返回指向向量底层存储的内部指针。 But on the next iteration of the loop, this array
gets destroyed, as I explained above, leaving a dangling pointer to the contents of the destroyed vector, behind.但是在循环的下一次迭代中,这个
array
被破坏了,正如我上面解释的那样,留下一个指向被破坏向量内容的悬空指针,在后面。
As such, subsequent usage of the pointer becomes undefined behavior.因此,指针的后续使用变成了未定义的行为。 With or without
std::move
(which means nothing here).有或没有
std::move
(这里没有任何意义)。
To fix this, you need to take into greater consideration what smart pointers are;要解决这个问题,您需要更多地考虑智能指针是什么; and how they work;
以及它们是如何工作的; what
std::vector
is, what its data()
method returns; std::vector
是什么,它的data()
方法返回什么; object lifetime and scoping in C++; object 的生命周期和 C++ 中的范围; then combine this together in a way that makes it work for your program correctly.
然后将其组合在一起,使其正确地适用于您的程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.