C++ Why emplacing object in vector segfaults?What are the differences between a pointer variable and a reference variable in C++?With arrays, why is it the case that a[5] == 5[a]?The Definitive C++ Book Guide and ListWhy is “using namespace std;” considered bad practice?What is the “-->” operator in C++?Why do we need virtual functions in C++?Why are elementwise additions much faster in separate loops than in a combined loop?Why is reading lines from stdin much slower in C++ than Python?Why is processing a sorted array faster than processing an unsorted array?Why should I use a pointer rather than the object itself?
Is the first page of Novel really that important?
Export economy of Mars
Why is the Vasa Museum in Stockholm so Popular?
Is this popular optical illusion made of a grey-scale image with coloured lines?
HackerRank Implement Queue using two stacks Solution
What is a summary of basic Jewish metaphysics or theology?
How do I find version of Intel graphics card drivers installed?
Empty proof as standalone
What is Albrecht Dürer's Perspective Machine drawing style?
Skipping same old introductions
Why isn't the new LEGO CV joint available on Bricklink or Brickowl?
Can there be multiple energy eigenstates corresponding to the same eigenvalue of a Hamiltonian (Pauli-X)?
How to design an effective polearm-bow hybrid?
Can an unintentional murderer leave Ir Miklat for Shalosh Regalim?
Who's behind community AMIs on Amazon EC2?
Feedback diagram
In MTG, was there ever a five-color deck that worked well?
Does WSL2 runs Linux in a virtual machine or alongside windows Kernel?
Lower bound for the number of lattice points on high dimensional spheres
Is it uncompelling to continue the story with lower stakes?
Do moonless nights cause dim light to become darkness, and bright light (e.g. from torches) to become dim light?
Approximating an expression for a potential
Deflecting lasers with lightsabers
What is the most 'environmentally friendly' way to learn to fly?
C++ Why emplacing object in vector segfaults?
What are the differences between a pointer variable and a reference variable in C++?With arrays, why is it the case that a[5] == 5[a]?The Definitive C++ Book Guide and ListWhy is “using namespace std;” considered bad practice?What is the “-->” operator in C++?Why do we need virtual functions in C++?Why are elementwise additions much faster in separate loops than in a combined loop?Why is reading lines from stdin much slower in C++ than Python?Why is processing a sorted array faster than processing an unsorted array?Why should I use a pointer rather than the object itself?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I want to create a vector of "Act" objects that contain pointers to either "Eat" or "Drink" dynamically allocated objects. The new objects are being emplaced like so:
action_vector.emplace_back(Act::BehaviorType::eat);
However, it is seg-faulting and I can't figure out why. I thought that emplace_back would implicitly call the move constructor, not the destructor, but for some reason it is, which (I think) is what is screwing everything up.
Is there any way to successfully create a vector of such objects?
Here is the rest of the code along with its output. Sorry if it's a little verbose, but basically it's just a strategy pattern.
#include <iostream>
#include <vector>
class IBehavior
public:
IBehavior() = default;
virtual ~IBehavior() = default;
virtual void execute() = 0;
;
class Drink : public IBehavior
public:
Drink(): IBehavior()
~Drink()
void execute() std::cout << "Drinking" << std::endl;
;
class Eat : public IBehavior
public:
Eat(): IBehavior()
~Eat()
void execute() std::cout << "Eating" << std::endl;
;
class Act
IBehavior * b;
public:
enum class BehaviorType eat = 0, drink = 1 ;
Act() = default;
~Act()
std::cout << "Calling the destructor" << std::endl;
delete b;
Act(BehaviorType b_type) SetBehavior(b_type);
Act(Act&& act)
std::cout << "Calling the move constructor" << std::endl;
this->b = act.b;
void SetBehavior(BehaviorType b_type)
if(b_type == BehaviorType::eat) b = new Eat();
if(b_type == BehaviorType::drink) b = new Drink();
void execute() b->execute();
;
int main(int argc, char * argv[])
std::vector<Act> action_vector;
for(int i = 0; i < 10; ++i)
action_vector.emplace_back(Act::BehaviorType::eat);
action_vector[i].execute();
return 0;
output:
Eating
Calling the move constructor
Calling the destructor
Eating
Calling the move constructor
Calling the move constructor
Calling the destructor
Calling the destructor
Segmentation fault: 11
c++ pointers vector strategy-pattern
add a comment |
I want to create a vector of "Act" objects that contain pointers to either "Eat" or "Drink" dynamically allocated objects. The new objects are being emplaced like so:
action_vector.emplace_back(Act::BehaviorType::eat);
However, it is seg-faulting and I can't figure out why. I thought that emplace_back would implicitly call the move constructor, not the destructor, but for some reason it is, which (I think) is what is screwing everything up.
Is there any way to successfully create a vector of such objects?
Here is the rest of the code along with its output. Sorry if it's a little verbose, but basically it's just a strategy pattern.
#include <iostream>
#include <vector>
class IBehavior
public:
IBehavior() = default;
virtual ~IBehavior() = default;
virtual void execute() = 0;
;
class Drink : public IBehavior
public:
Drink(): IBehavior()
~Drink()
void execute() std::cout << "Drinking" << std::endl;
;
class Eat : public IBehavior
public:
Eat(): IBehavior()
~Eat()
void execute() std::cout << "Eating" << std::endl;
;
class Act
IBehavior * b;
public:
enum class BehaviorType eat = 0, drink = 1 ;
Act() = default;
~Act()
std::cout << "Calling the destructor" << std::endl;
delete b;
Act(BehaviorType b_type) SetBehavior(b_type);
Act(Act&& act)
std::cout << "Calling the move constructor" << std::endl;
this->b = act.b;
void SetBehavior(BehaviorType b_type)
if(b_type == BehaviorType::eat) b = new Eat();
if(b_type == BehaviorType::drink) b = new Drink();
void execute() b->execute();
;
int main(int argc, char * argv[])
std::vector<Act> action_vector;
for(int i = 0; i < 10; ++i)
action_vector.emplace_back(Act::BehaviorType::eat);
action_vector[i].execute();
return 0;
output:
Eating
Calling the move constructor
Calling the destructor
Eating
Calling the move constructor
Calling the move constructor
Calling the destructor
Calling the destructor
Segmentation fault: 11
c++ pointers vector strategy-pattern
When a move constructor or move assignment "steals" a single-use resource, it must not leave it in the original object to be reaped by the destructor. So in this case, after copying pointerb
intothis
(this->b = act.b
), it should setact.b = nullptr
.
– Perette
Mar 27 at 2:36
add a comment |
I want to create a vector of "Act" objects that contain pointers to either "Eat" or "Drink" dynamically allocated objects. The new objects are being emplaced like so:
action_vector.emplace_back(Act::BehaviorType::eat);
However, it is seg-faulting and I can't figure out why. I thought that emplace_back would implicitly call the move constructor, not the destructor, but for some reason it is, which (I think) is what is screwing everything up.
Is there any way to successfully create a vector of such objects?
Here is the rest of the code along with its output. Sorry if it's a little verbose, but basically it's just a strategy pattern.
#include <iostream>
#include <vector>
class IBehavior
public:
IBehavior() = default;
virtual ~IBehavior() = default;
virtual void execute() = 0;
;
class Drink : public IBehavior
public:
Drink(): IBehavior()
~Drink()
void execute() std::cout << "Drinking" << std::endl;
;
class Eat : public IBehavior
public:
Eat(): IBehavior()
~Eat()
void execute() std::cout << "Eating" << std::endl;
;
class Act
IBehavior * b;
public:
enum class BehaviorType eat = 0, drink = 1 ;
Act() = default;
~Act()
std::cout << "Calling the destructor" << std::endl;
delete b;
Act(BehaviorType b_type) SetBehavior(b_type);
Act(Act&& act)
std::cout << "Calling the move constructor" << std::endl;
this->b = act.b;
void SetBehavior(BehaviorType b_type)
if(b_type == BehaviorType::eat) b = new Eat();
if(b_type == BehaviorType::drink) b = new Drink();
void execute() b->execute();
;
int main(int argc, char * argv[])
std::vector<Act> action_vector;
for(int i = 0; i < 10; ++i)
action_vector.emplace_back(Act::BehaviorType::eat);
action_vector[i].execute();
return 0;
output:
Eating
Calling the move constructor
Calling the destructor
Eating
Calling the move constructor
Calling the move constructor
Calling the destructor
Calling the destructor
Segmentation fault: 11
c++ pointers vector strategy-pattern
I want to create a vector of "Act" objects that contain pointers to either "Eat" or "Drink" dynamically allocated objects. The new objects are being emplaced like so:
action_vector.emplace_back(Act::BehaviorType::eat);
However, it is seg-faulting and I can't figure out why. I thought that emplace_back would implicitly call the move constructor, not the destructor, but for some reason it is, which (I think) is what is screwing everything up.
Is there any way to successfully create a vector of such objects?
Here is the rest of the code along with its output. Sorry if it's a little verbose, but basically it's just a strategy pattern.
#include <iostream>
#include <vector>
class IBehavior
public:
IBehavior() = default;
virtual ~IBehavior() = default;
virtual void execute() = 0;
;
class Drink : public IBehavior
public:
Drink(): IBehavior()
~Drink()
void execute() std::cout << "Drinking" << std::endl;
;
class Eat : public IBehavior
public:
Eat(): IBehavior()
~Eat()
void execute() std::cout << "Eating" << std::endl;
;
class Act
IBehavior * b;
public:
enum class BehaviorType eat = 0, drink = 1 ;
Act() = default;
~Act()
std::cout << "Calling the destructor" << std::endl;
delete b;
Act(BehaviorType b_type) SetBehavior(b_type);
Act(Act&& act)
std::cout << "Calling the move constructor" << std::endl;
this->b = act.b;
void SetBehavior(BehaviorType b_type)
if(b_type == BehaviorType::eat) b = new Eat();
if(b_type == BehaviorType::drink) b = new Drink();
void execute() b->execute();
;
int main(int argc, char * argv[])
std::vector<Act> action_vector;
for(int i = 0; i < 10; ++i)
action_vector.emplace_back(Act::BehaviorType::eat);
action_vector[i].execute();
return 0;
output:
Eating
Calling the move constructor
Calling the destructor
Eating
Calling the move constructor
Calling the move constructor
Calling the destructor
Calling the destructor
Segmentation fault: 11
c++ pointers vector strategy-pattern
c++ pointers vector strategy-pattern
asked Mar 27 at 1:31
ParadoxParadox
8557 silver badges16 bronze badges
8557 silver badges16 bronze badges
When a move constructor or move assignment "steals" a single-use resource, it must not leave it in the original object to be reaped by the destructor. So in this case, after copying pointerb
intothis
(this->b = act.b
), it should setact.b = nullptr
.
– Perette
Mar 27 at 2:36
add a comment |
When a move constructor or move assignment "steals" a single-use resource, it must not leave it in the original object to be reaped by the destructor. So in this case, after copying pointerb
intothis
(this->b = act.b
), it should setact.b = nullptr
.
– Perette
Mar 27 at 2:36
When a move constructor or move assignment "steals" a single-use resource, it must not leave it in the original object to be reaped by the destructor. So in this case, after copying pointer
b
into this
(this->b = act.b
), it should set act.b = nullptr
.– Perette
Mar 27 at 2:36
When a move constructor or move assignment "steals" a single-use resource, it must not leave it in the original object to be reaped by the destructor. So in this case, after copying pointer
b
into this
(this->b = act.b
), it should set act.b = nullptr
.– Perette
Mar 27 at 2:36
add a comment |
1 Answer
1
active
oldest
votes
Your move constructor copies b
, and destructor deletes b
, so if you move construct an instance then the same pointer value will be deleted twice which has undefined behaviour.
General solution: Use a smart pointer.
Another bug: Default constructor leaves b
uninitialised. When a default constructed object is destroyed, the uninitialised pointer is deleted and behaviour is undefined. Smart pointer fixes this also.
Does not segfault on a mac, LLVM version 10.0.0 (clang-1000.10.44.2)
– Gardener
Mar 27 at 1:45
@Gardener well, the behaviour is undefined. It's not guaranteed to segfault.
– eerorika
Mar 27 at 1:46
Thanks, that's a good point. However, the issue still remains if I write "this->b = std::move(act.b);" in the move constructor (Is this because the "original" b is still be destructed upon but is now empty?). I probably should be using smart pointers but I really want to fix my intuition w.r.t what's happening with regular pointers first. How would this situation be handled with regular pointers?
– Paradox
Mar 27 at 1:47
1
Moving a bare pointer is same as copying the pointer. It solves nothing. You can fix this bug by assigningact.b = nullptr
.
– eerorika
Mar 27 at 1:51
Thanks, think I get it, also TIL deleting nullptr is safe.
– Paradox
Mar 27 at 1:57
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55368498%2fc-why-emplacing-object-in-vector-segfaults%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your move constructor copies b
, and destructor deletes b
, so if you move construct an instance then the same pointer value will be deleted twice which has undefined behaviour.
General solution: Use a smart pointer.
Another bug: Default constructor leaves b
uninitialised. When a default constructed object is destroyed, the uninitialised pointer is deleted and behaviour is undefined. Smart pointer fixes this also.
Does not segfault on a mac, LLVM version 10.0.0 (clang-1000.10.44.2)
– Gardener
Mar 27 at 1:45
@Gardener well, the behaviour is undefined. It's not guaranteed to segfault.
– eerorika
Mar 27 at 1:46
Thanks, that's a good point. However, the issue still remains if I write "this->b = std::move(act.b);" in the move constructor (Is this because the "original" b is still be destructed upon but is now empty?). I probably should be using smart pointers but I really want to fix my intuition w.r.t what's happening with regular pointers first. How would this situation be handled with regular pointers?
– Paradox
Mar 27 at 1:47
1
Moving a bare pointer is same as copying the pointer. It solves nothing. You can fix this bug by assigningact.b = nullptr
.
– eerorika
Mar 27 at 1:51
Thanks, think I get it, also TIL deleting nullptr is safe.
– Paradox
Mar 27 at 1:57
add a comment |
Your move constructor copies b
, and destructor deletes b
, so if you move construct an instance then the same pointer value will be deleted twice which has undefined behaviour.
General solution: Use a smart pointer.
Another bug: Default constructor leaves b
uninitialised. When a default constructed object is destroyed, the uninitialised pointer is deleted and behaviour is undefined. Smart pointer fixes this also.
Does not segfault on a mac, LLVM version 10.0.0 (clang-1000.10.44.2)
– Gardener
Mar 27 at 1:45
@Gardener well, the behaviour is undefined. It's not guaranteed to segfault.
– eerorika
Mar 27 at 1:46
Thanks, that's a good point. However, the issue still remains if I write "this->b = std::move(act.b);" in the move constructor (Is this because the "original" b is still be destructed upon but is now empty?). I probably should be using smart pointers but I really want to fix my intuition w.r.t what's happening with regular pointers first. How would this situation be handled with regular pointers?
– Paradox
Mar 27 at 1:47
1
Moving a bare pointer is same as copying the pointer. It solves nothing. You can fix this bug by assigningact.b = nullptr
.
– eerorika
Mar 27 at 1:51
Thanks, think I get it, also TIL deleting nullptr is safe.
– Paradox
Mar 27 at 1:57
add a comment |
Your move constructor copies b
, and destructor deletes b
, so if you move construct an instance then the same pointer value will be deleted twice which has undefined behaviour.
General solution: Use a smart pointer.
Another bug: Default constructor leaves b
uninitialised. When a default constructed object is destroyed, the uninitialised pointer is deleted and behaviour is undefined. Smart pointer fixes this also.
Your move constructor copies b
, and destructor deletes b
, so if you move construct an instance then the same pointer value will be deleted twice which has undefined behaviour.
General solution: Use a smart pointer.
Another bug: Default constructor leaves b
uninitialised. When a default constructed object is destroyed, the uninitialised pointer is deleted and behaviour is undefined. Smart pointer fixes this also.
edited Mar 27 at 1:53
answered Mar 27 at 1:33
eerorikaeerorika
102k6 gold badges81 silver badges157 bronze badges
102k6 gold badges81 silver badges157 bronze badges
Does not segfault on a mac, LLVM version 10.0.0 (clang-1000.10.44.2)
– Gardener
Mar 27 at 1:45
@Gardener well, the behaviour is undefined. It's not guaranteed to segfault.
– eerorika
Mar 27 at 1:46
Thanks, that's a good point. However, the issue still remains if I write "this->b = std::move(act.b);" in the move constructor (Is this because the "original" b is still be destructed upon but is now empty?). I probably should be using smart pointers but I really want to fix my intuition w.r.t what's happening with regular pointers first. How would this situation be handled with regular pointers?
– Paradox
Mar 27 at 1:47
1
Moving a bare pointer is same as copying the pointer. It solves nothing. You can fix this bug by assigningact.b = nullptr
.
– eerorika
Mar 27 at 1:51
Thanks, think I get it, also TIL deleting nullptr is safe.
– Paradox
Mar 27 at 1:57
add a comment |
Does not segfault on a mac, LLVM version 10.0.0 (clang-1000.10.44.2)
– Gardener
Mar 27 at 1:45
@Gardener well, the behaviour is undefined. It's not guaranteed to segfault.
– eerorika
Mar 27 at 1:46
Thanks, that's a good point. However, the issue still remains if I write "this->b = std::move(act.b);" in the move constructor (Is this because the "original" b is still be destructed upon but is now empty?). I probably should be using smart pointers but I really want to fix my intuition w.r.t what's happening with regular pointers first. How would this situation be handled with regular pointers?
– Paradox
Mar 27 at 1:47
1
Moving a bare pointer is same as copying the pointer. It solves nothing. You can fix this bug by assigningact.b = nullptr
.
– eerorika
Mar 27 at 1:51
Thanks, think I get it, also TIL deleting nullptr is safe.
– Paradox
Mar 27 at 1:57
Does not segfault on a mac, LLVM version 10.0.0 (clang-1000.10.44.2)
– Gardener
Mar 27 at 1:45
Does not segfault on a mac, LLVM version 10.0.0 (clang-1000.10.44.2)
– Gardener
Mar 27 at 1:45
@Gardener well, the behaviour is undefined. It's not guaranteed to segfault.
– eerorika
Mar 27 at 1:46
@Gardener well, the behaviour is undefined. It's not guaranteed to segfault.
– eerorika
Mar 27 at 1:46
Thanks, that's a good point. However, the issue still remains if I write "this->b = std::move(act.b);" in the move constructor (Is this because the "original" b is still be destructed upon but is now empty?). I probably should be using smart pointers but I really want to fix my intuition w.r.t what's happening with regular pointers first. How would this situation be handled with regular pointers?
– Paradox
Mar 27 at 1:47
Thanks, that's a good point. However, the issue still remains if I write "this->b = std::move(act.b);" in the move constructor (Is this because the "original" b is still be destructed upon but is now empty?). I probably should be using smart pointers but I really want to fix my intuition w.r.t what's happening with regular pointers first. How would this situation be handled with regular pointers?
– Paradox
Mar 27 at 1:47
1
1
Moving a bare pointer is same as copying the pointer. It solves nothing. You can fix this bug by assigning
act.b = nullptr
.– eerorika
Mar 27 at 1:51
Moving a bare pointer is same as copying the pointer. It solves nothing. You can fix this bug by assigning
act.b = nullptr
.– eerorika
Mar 27 at 1:51
Thanks, think I get it, also TIL deleting nullptr is safe.
– Paradox
Mar 27 at 1:57
Thanks, think I get it, also TIL deleting nullptr is safe.
– Paradox
Mar 27 at 1:57
add a comment |
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55368498%2fc-why-emplacing-object-in-vector-segfaults%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
When a move constructor or move assignment "steals" a single-use resource, it must not leave it in the original object to be reaped by the destructor. So in this case, after copying pointer
b
intothis
(this->b = act.b
), it should setact.b = nullptr
.– Perette
Mar 27 at 2:36