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;








1















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









share|improve this question
























  • 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

















1















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









share|improve this question
























  • 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













1












1








1


1






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









share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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 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
















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












1 Answer
1






active

oldest

votes


















4














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.






share|improve this answer



























  • 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 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










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
);



);













draft saved

draft discarded


















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









4














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.






share|improve this answer



























  • 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 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















4














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.






share|improve this answer



























  • 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 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













4












4








4







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.






share|improve this answer















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.







share|improve this answer














share|improve this answer



share|improve this answer








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 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

















  • 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 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
















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








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.



















draft saved

draft discarded
















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

은진 송씨 목차 역사 본관 분파 인물 조선 왕실과의 인척 관계 집성촌 항렬자 인구 같이 보기 각주 둘러보기 메뉴은진 송씨세종실록 149권, 지리지 충청도 공주목 은진현