通过右值传递给 unordered_map 时释放内存
the memory is released when passing to unordered_map by rvalue
我用 -std=c++17
构建了它,并尝试了 g++
和 clang++
,例如 clang++ -std=c++17 <file>
。它显示了相同的结果。
unordered_map
将unordered_map传递给函数中的右值参数并将其分配给另一个引用。而且内存不允许超出函数范围。
#include <iostream>
#include <string>
#include <unordered_map>
#include <list>
using namespace std;
typedef unordered_map<string, string> kw_t;
struct Bar {
kw_t &foo;
string bar;
};
list<Bar> bars;
void test(kw_t &&foo) {
cout << &foo["a"] << endl;
bars.emplace_back(Bar { .foo = foo, .bar = "bar" });
cout << &bars.front().foo["a"] << endl;
}
int main()
{
test({{"a", "b"}});
cout << &bars.front().foo["a"] << endl;
return 0;
}
它有输出:
0x1f3ded8
0x1f3ded8
[1] 9776 segmentation fault (core dumped) ./a.o
列表
但对于其他类,例如列表或自定义结构,代码可以工作。
#include <iostream>
#include <list>
#include <string>
using namespace std;
typedef list<string> args_t;
struct Bar {
args_t &foo;
string bar;
};
list<Bar> bars;
void test(args_t &&foo) {
cout << &foo.front() << endl;
bars.emplace_back(Bar { .foo = foo, .bar = "bar" });
cout << &bars.front().foo.front() << endl;
}
int main()
{
test({"a", "b"});
cout << &bars.front().foo.front() << endl;
return 0;
}
它打印了:
0x15a7ec0
0x15a7ec0
0x15a7ec0
为什么第二个能用,第一个不行?
编辑 1:
clang 版本 7.1.0
g++ (海湾合作委员会) 9.3.0
Why can the second one work but the first not?
在这两种情况下,程序的行为都是未定义的。因此,它“可以”或“可能”或“被允许”[=19=]似乎 起作用(对于您认为“正在工作”的任何事物)。或者不“工作”。或者有任何其他行为。
澄清一下,引用 bars.front().foo
绑定到的临时对象的生命周期已经结束,因此引用无效。通过无效引用调用成员函数会导致未定义的行为。
Is it an erroneous behavior for compiler?
没有。编译器运行正常。但是你的程序坏了。
我用 -std=c++17
构建了它,并尝试了 g++
和 clang++
,例如 clang++ -std=c++17 <file>
。它显示了相同的结果。
unordered_map
将unordered_map传递给函数中的右值参数并将其分配给另一个引用。而且内存不允许超出函数范围。
#include <iostream>
#include <string>
#include <unordered_map>
#include <list>
using namespace std;
typedef unordered_map<string, string> kw_t;
struct Bar {
kw_t &foo;
string bar;
};
list<Bar> bars;
void test(kw_t &&foo) {
cout << &foo["a"] << endl;
bars.emplace_back(Bar { .foo = foo, .bar = "bar" });
cout << &bars.front().foo["a"] << endl;
}
int main()
{
test({{"a", "b"}});
cout << &bars.front().foo["a"] << endl;
return 0;
}
它有输出:
0x1f3ded8
0x1f3ded8
[1] 9776 segmentation fault (core dumped) ./a.o
列表
但对于其他类,例如列表或自定义结构,代码可以工作。
#include <iostream>
#include <list>
#include <string>
using namespace std;
typedef list<string> args_t;
struct Bar {
args_t &foo;
string bar;
};
list<Bar> bars;
void test(args_t &&foo) {
cout << &foo.front() << endl;
bars.emplace_back(Bar { .foo = foo, .bar = "bar" });
cout << &bars.front().foo.front() << endl;
}
int main()
{
test({"a", "b"});
cout << &bars.front().foo.front() << endl;
return 0;
}
它打印了:
0x15a7ec0
0x15a7ec0
0x15a7ec0
为什么第二个能用,第一个不行?
编辑 1:
clang 版本 7.1.0
g++ (海湾合作委员会) 9.3.0
Why can the second one work but the first not?
在这两种情况下,程序的行为都是未定义的。因此,它“可以”或“可能”或“被允许”[=19=]似乎 起作用(对于您认为“正在工作”的任何事物)。或者不“工作”。或者有任何其他行为。
澄清一下,引用 bars.front().foo
绑定到的临时对象的生命周期已经结束,因此引用无效。通过无效引用调用成员函数会导致未定义的行为。
Is it an erroneous behavior for compiler?
没有。编译器运行正常。但是你的程序坏了。