Smart pointers get confused in initializer list
I am trying to run a simple piece of code with shared pointers.
//in the class definition
Rule(std::string name,
std::vector<std::vector<std::shared_ptr<RuleMember>>> rules);
...
//in function 'main'
shared_ptr<Rule> expression(new Rule("expression", {
{ identifier },
{ expression, add, identifier }
}));
Compilation was successful but "The program stops working" when I try to run it. I went through the code and it failed when execution leaves main
(this is the function that contains this code).
Interestingly, when I explicitly add a constructor around the expression, it works:
shared_ptr<Rule> expression(new Rule("expression", {
{ identifier },
{ shared_ptr<Rule> (expression), add, identifier }
}));
I have three questions:
- What happens when I pass a local variable
shared_ptr
(expression
in this case) to the initializer list? I thought the copy constructor would be called, creating a new oneshared_ptr
to initialize collection I. - Is it possible that this one
shared_ptr
in the collection that is pointed toexpression
in the function scope will not contain a valid pointer just because the constructorexpression
hasn't finished yet? - Does it matter that the program stops working
{ __atomic_fetch_add(__mem, __val, __ATOMIC_ACQ_REL); }
somewhere in<atomicity.h>
, or is it just a random location?
+3
source to share
1 answer
A variable is not initialized when used inside an initializer list. See what happens:
#include <memory>
#include <string>
#include <vector>
#include <iostream>
using std::shared_ptr;
using std::string;
using std::vector;
struct Rule {
string name;
vector<vector<shared_ptr<Rule>>> rules;
Rule(string name,
vector<vector<shared_ptr<Rule>>> rules)
: name(name), rules(rules) {}
};
using std::cout;
using std::endl;
int main() {
shared_ptr<Rule> identifier, add;
shared_ptr<Rule> expression(new Rule("expression", {
{ identifier },
{ expression, add, identifier }
}));
cout << expression->name << ": "
<< (uintptr_t)expression.get() << " ? "
<< (uintptr_t)expression->rules[1][0].get();
}
Output:
expression: 536937312? 2282820
An attempt to access failed expression->rules[1][0]->name
;
+1
source to share