Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
282 views
in Technique[技术] by (71.8m points)

c++ - the memory is released when passing to unordered_map by rvalue

I bulit it with -std=c++17 and tried both g++ and clang++ such as clang++ -std=c++17 <file>. It showed the same results.

unordered_map

Pass an unordered_map to rvalue parameter in a function and assign it to another reference. And the memory is not allowed out of the function.

#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;
}

And it has output:

0x1f3ded8
0x1f3ded8
[1]    9776 segmentation fault (core dumped)  ./a.o

list

But for other classes, such as list or self defined struct, the code can work.

#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;
}

It printed:

0x15a7ec0
0x15a7ec0
0x15a7ec0

Why can the second one work but the first not?

Edit1:

clang version 7.1.0

g++ (GCC) 9.3.0


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Why can the second one work but the first not?

In both cases, behaviour of the program is undefined. So, it "can" or "may" or "is allowed to" appear to work (for whatever you perceive as "woking"). Or to not "work". Or to have any other behaviour.

To clarify, the lifetime of the temporary object to which the reference bars.front().foo was bound has ended, and so the reference is invalid. Calling a member function through the invalid reference results in undefined behaviour.

Is it an erroneous behavior for compiler?

No. The compiler is behaving correctly. Your programs however are broken.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to MLink Developer Q&A Community for programmer and developer-Open, Learning and Share
...