C++ make_shared calling destructor twice [closed]
I have some code that's confusing me. I've been learning about shared_pointers and am following a guide on youtube. I am using make_shared to construct my Dog, and assign the shared pointer to p.
class Dog
{
private:
std::string name;
public:
Dog(std::string _name):
name(_name)
{
std::cout << "Creating dog with name " << name << std::endl;
}
~Dog() { std::cout << "Destroying dog!" << std::endl; }
void bark()
{
std::cout << name << " barks like a Dog! Woof!" << std::endl;
}
};
std::shared_ptr<Dog> foo()
{
std::cout << "Entering foo" << std::endl;
std::shared_ptr<Dog> p = std::make_shared<Dog>("Tank"); //will be deleted when freed off stack
std::cout << "Dog use count = " << p.use_count() << std::endl;
std::shared_ptr<Dog> p2 = p;
std::cout << "Dog use count = " << p.use_count() << std::endl;
std::cout << "Returning first pointer from foo!" << std::endl;
return p;
}
int main()
{
std::shared_ptr<Dog> p = foo();
std::cout << "Dog use count = " << p.use_count() << std::endl;
return 0;
}
Compiled with
g++ shared_ptr.cpp
However, here is my output:
Entering foo
Creating dog with name Tank
Destroying dog!
Destroying dog!
Dog use count = 1
Dog use count = 2
Returning first pointer from foo!
Could someone explain the logic of constructing and then double destructing somehow?
c++ shared-ptr
closed as off-topic by VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru Nov 28 '18 at 21:44
This question appears to be off-topic. The users who voted to close gave this specific reason:
- "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example." – VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru
If this question can be reworded to fit the rules in the help center, please edit the question.
|
show 20 more comments
I have some code that's confusing me. I've been learning about shared_pointers and am following a guide on youtube. I am using make_shared to construct my Dog, and assign the shared pointer to p.
class Dog
{
private:
std::string name;
public:
Dog(std::string _name):
name(_name)
{
std::cout << "Creating dog with name " << name << std::endl;
}
~Dog() { std::cout << "Destroying dog!" << std::endl; }
void bark()
{
std::cout << name << " barks like a Dog! Woof!" << std::endl;
}
};
std::shared_ptr<Dog> foo()
{
std::cout << "Entering foo" << std::endl;
std::shared_ptr<Dog> p = std::make_shared<Dog>("Tank"); //will be deleted when freed off stack
std::cout << "Dog use count = " << p.use_count() << std::endl;
std::shared_ptr<Dog> p2 = p;
std::cout << "Dog use count = " << p.use_count() << std::endl;
std::cout << "Returning first pointer from foo!" << std::endl;
return p;
}
int main()
{
std::shared_ptr<Dog> p = foo();
std::cout << "Dog use count = " << p.use_count() << std::endl;
return 0;
}
Compiled with
g++ shared_ptr.cpp
However, here is my output:
Entering foo
Creating dog with name Tank
Destroying dog!
Destroying dog!
Dog use count = 1
Dog use count = 2
Returning first pointer from foo!
Could someone explain the logic of constructing and then double destructing somehow?
c++ shared-ptr
closed as off-topic by VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru Nov 28 '18 at 21:44
This question appears to be off-topic. The users who voted to close gave this specific reason:
- "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example." – VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru
If this question can be reworded to fit the rules in the help center, please edit the question.
3
You should pay attention to which instance is being destructed. Step through in a debugger to find out. You may have created an accidental copy in this code.
– tadman
Nov 28 '18 at 21:02
5
I cannot reproduce. What compiler and version are you using? Do you have optimizations turned on?
– NathanOliver
Nov 28 '18 at 21:02
3
Tip: Accept string arguments asconst std::string&to avoid making endless, pointless copies.
– tadman
Nov 28 '18 at 21:02
2
You should show the code callingfoo. Also note thatDogclass has implicit copy constructor and assignment operators.
– VTT
Nov 28 '18 at 21:04
@tadman In this case, that advice is wrong, because it means at least one copy needs to be made, namely from the parameter to the member. To minimize copies, accept the argument by value and then move it into the member.
– Brian
Nov 28 '18 at 21:04
|
show 20 more comments
I have some code that's confusing me. I've been learning about shared_pointers and am following a guide on youtube. I am using make_shared to construct my Dog, and assign the shared pointer to p.
class Dog
{
private:
std::string name;
public:
Dog(std::string _name):
name(_name)
{
std::cout << "Creating dog with name " << name << std::endl;
}
~Dog() { std::cout << "Destroying dog!" << std::endl; }
void bark()
{
std::cout << name << " barks like a Dog! Woof!" << std::endl;
}
};
std::shared_ptr<Dog> foo()
{
std::cout << "Entering foo" << std::endl;
std::shared_ptr<Dog> p = std::make_shared<Dog>("Tank"); //will be deleted when freed off stack
std::cout << "Dog use count = " << p.use_count() << std::endl;
std::shared_ptr<Dog> p2 = p;
std::cout << "Dog use count = " << p.use_count() << std::endl;
std::cout << "Returning first pointer from foo!" << std::endl;
return p;
}
int main()
{
std::shared_ptr<Dog> p = foo();
std::cout << "Dog use count = " << p.use_count() << std::endl;
return 0;
}
Compiled with
g++ shared_ptr.cpp
However, here is my output:
Entering foo
Creating dog with name Tank
Destroying dog!
Destroying dog!
Dog use count = 1
Dog use count = 2
Returning first pointer from foo!
Could someone explain the logic of constructing and then double destructing somehow?
c++ shared-ptr
I have some code that's confusing me. I've been learning about shared_pointers and am following a guide on youtube. I am using make_shared to construct my Dog, and assign the shared pointer to p.
class Dog
{
private:
std::string name;
public:
Dog(std::string _name):
name(_name)
{
std::cout << "Creating dog with name " << name << std::endl;
}
~Dog() { std::cout << "Destroying dog!" << std::endl; }
void bark()
{
std::cout << name << " barks like a Dog! Woof!" << std::endl;
}
};
std::shared_ptr<Dog> foo()
{
std::cout << "Entering foo" << std::endl;
std::shared_ptr<Dog> p = std::make_shared<Dog>("Tank"); //will be deleted when freed off stack
std::cout << "Dog use count = " << p.use_count() << std::endl;
std::shared_ptr<Dog> p2 = p;
std::cout << "Dog use count = " << p.use_count() << std::endl;
std::cout << "Returning first pointer from foo!" << std::endl;
return p;
}
int main()
{
std::shared_ptr<Dog> p = foo();
std::cout << "Dog use count = " << p.use_count() << std::endl;
return 0;
}
Compiled with
g++ shared_ptr.cpp
However, here is my output:
Entering foo
Creating dog with name Tank
Destroying dog!
Destroying dog!
Dog use count = 1
Dog use count = 2
Returning first pointer from foo!
Could someone explain the logic of constructing and then double destructing somehow?
c++ shared-ptr
c++ shared-ptr
edited Nov 28 '18 at 21:45
briansrls
asked Nov 28 '18 at 20:59
briansrlsbriansrls
446317
446317
closed as off-topic by VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru Nov 28 '18 at 21:44
This question appears to be off-topic. The users who voted to close gave this specific reason:
- "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example." – VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru
If this question can be reworded to fit the rules in the help center, please edit the question.
closed as off-topic by VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru Nov 28 '18 at 21:44
This question appears to be off-topic. The users who voted to close gave this specific reason:
- "Questions seeking debugging help ("why isn't this code working?") must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. See: How to create a Minimal, Complete, and Verifiable example." – VTT, NathanOliver, Slava, Killzone Kid, C-Pound Guru
If this question can be reworded to fit the rules in the help center, please edit the question.
3
You should pay attention to which instance is being destructed. Step through in a debugger to find out. You may have created an accidental copy in this code.
– tadman
Nov 28 '18 at 21:02
5
I cannot reproduce. What compiler and version are you using? Do you have optimizations turned on?
– NathanOliver
Nov 28 '18 at 21:02
3
Tip: Accept string arguments asconst std::string&to avoid making endless, pointless copies.
– tadman
Nov 28 '18 at 21:02
2
You should show the code callingfoo. Also note thatDogclass has implicit copy constructor and assignment operators.
– VTT
Nov 28 '18 at 21:04
@tadman In this case, that advice is wrong, because it means at least one copy needs to be made, namely from the parameter to the member. To minimize copies, accept the argument by value and then move it into the member.
– Brian
Nov 28 '18 at 21:04
|
show 20 more comments
3
You should pay attention to which instance is being destructed. Step through in a debugger to find out. You may have created an accidental copy in this code.
– tadman
Nov 28 '18 at 21:02
5
I cannot reproduce. What compiler and version are you using? Do you have optimizations turned on?
– NathanOliver
Nov 28 '18 at 21:02
3
Tip: Accept string arguments asconst std::string&to avoid making endless, pointless copies.
– tadman
Nov 28 '18 at 21:02
2
You should show the code callingfoo. Also note thatDogclass has implicit copy constructor and assignment operators.
– VTT
Nov 28 '18 at 21:04
@tadman In this case, that advice is wrong, because it means at least one copy needs to be made, namely from the parameter to the member. To minimize copies, accept the argument by value and then move it into the member.
– Brian
Nov 28 '18 at 21:04
3
3
You should pay attention to which instance is being destructed. Step through in a debugger to find out. You may have created an accidental copy in this code.
– tadman
Nov 28 '18 at 21:02
You should pay attention to which instance is being destructed. Step through in a debugger to find out. You may have created an accidental copy in this code.
– tadman
Nov 28 '18 at 21:02
5
5
I cannot reproduce. What compiler and version are you using? Do you have optimizations turned on?
– NathanOliver
Nov 28 '18 at 21:02
I cannot reproduce. What compiler and version are you using? Do you have optimizations turned on?
– NathanOliver
Nov 28 '18 at 21:02
3
3
Tip: Accept string arguments as
const std::string& to avoid making endless, pointless copies.– tadman
Nov 28 '18 at 21:02
Tip: Accept string arguments as
const std::string& to avoid making endless, pointless copies.– tadman
Nov 28 '18 at 21:02
2
2
You should show the code calling
foo. Also note that Dog class has implicit copy constructor and assignment operators.– VTT
Nov 28 '18 at 21:04
You should show the code calling
foo. Also note that Dog class has implicit copy constructor and assignment operators.– VTT
Nov 28 '18 at 21:04
@tadman In this case, that advice is wrong, because it means at least one copy needs to be made, namely from the parameter to the member. To minimize copies, accept the argument by value and then move it into the member.
– Brian
Nov 28 '18 at 21:04
@tadman In this case, that advice is wrong, because it means at least one copy needs to be made, namely from the parameter to the member. To minimize copies, accept the argument by value and then move it into the member.
– Brian
Nov 28 '18 at 21:04
|
show 20 more comments
1 Answer
1
active
oldest
votes
I think I've figured it out.
I tried compiling on centos with
g++ shared_ptr.cpp
But the compiler complains that shared_ptr is not a part of std. Changing to
g++ -std=c++11 shared_ptr.cpp
makes compilation successful, and I see the behavior I would expect (no double destruction).
My mac's makefile only specified
g++ shared_ptr.cpp
I checked my default c standard on my mac, and it is set to 199711L (1997ish). Even though this is not c++11, it seems like it was able to compile although the behavior is obviously weird.
On centOS, the default std is also 199711L, but compilation failed. It sounds like this is undefined behavior and very dangerous.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I think I've figured it out.
I tried compiling on centos with
g++ shared_ptr.cpp
But the compiler complains that shared_ptr is not a part of std. Changing to
g++ -std=c++11 shared_ptr.cpp
makes compilation successful, and I see the behavior I would expect (no double destruction).
My mac's makefile only specified
g++ shared_ptr.cpp
I checked my default c standard on my mac, and it is set to 199711L (1997ish). Even though this is not c++11, it seems like it was able to compile although the behavior is obviously weird.
On centOS, the default std is also 199711L, but compilation failed. It sounds like this is undefined behavior and very dangerous.
add a comment |
I think I've figured it out.
I tried compiling on centos with
g++ shared_ptr.cpp
But the compiler complains that shared_ptr is not a part of std. Changing to
g++ -std=c++11 shared_ptr.cpp
makes compilation successful, and I see the behavior I would expect (no double destruction).
My mac's makefile only specified
g++ shared_ptr.cpp
I checked my default c standard on my mac, and it is set to 199711L (1997ish). Even though this is not c++11, it seems like it was able to compile although the behavior is obviously weird.
On centOS, the default std is also 199711L, but compilation failed. It sounds like this is undefined behavior and very dangerous.
add a comment |
I think I've figured it out.
I tried compiling on centos with
g++ shared_ptr.cpp
But the compiler complains that shared_ptr is not a part of std. Changing to
g++ -std=c++11 shared_ptr.cpp
makes compilation successful, and I see the behavior I would expect (no double destruction).
My mac's makefile only specified
g++ shared_ptr.cpp
I checked my default c standard on my mac, and it is set to 199711L (1997ish). Even though this is not c++11, it seems like it was able to compile although the behavior is obviously weird.
On centOS, the default std is also 199711L, but compilation failed. It sounds like this is undefined behavior and very dangerous.
I think I've figured it out.
I tried compiling on centos with
g++ shared_ptr.cpp
But the compiler complains that shared_ptr is not a part of std. Changing to
g++ -std=c++11 shared_ptr.cpp
makes compilation successful, and I see the behavior I would expect (no double destruction).
My mac's makefile only specified
g++ shared_ptr.cpp
I checked my default c standard on my mac, and it is set to 199711L (1997ish). Even though this is not c++11, it seems like it was able to compile although the behavior is obviously weird.
On centOS, the default std is also 199711L, but compilation failed. It sounds like this is undefined behavior and very dangerous.
answered Nov 28 '18 at 21:26
briansrlsbriansrls
446317
446317
add a comment |
add a comment |
3
You should pay attention to which instance is being destructed. Step through in a debugger to find out. You may have created an accidental copy in this code.
– tadman
Nov 28 '18 at 21:02
5
I cannot reproduce. What compiler and version are you using? Do you have optimizations turned on?
– NathanOliver
Nov 28 '18 at 21:02
3
Tip: Accept string arguments as
const std::string&to avoid making endless, pointless copies.– tadman
Nov 28 '18 at 21:02
2
You should show the code calling
foo. Also note thatDogclass has implicit copy constructor and assignment operators.– VTT
Nov 28 '18 at 21:04
@tadman In this case, that advice is wrong, because it means at least one copy needs to be made, namely from the parameter to the member. To minimize copies, accept the argument by value and then move it into the member.
– Brian
Nov 28 '18 at 21:04