Overriding an object in memory with placement new Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live! Should we burninate the [wrap] tag?What uses are there for “placement new”?Method of derived class needs to downcast its parameterC++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?Overloading >> operator for a base classChoice for class designWhy should I use a pointer rather than the object itself?Copying Objects and its data members to another objectoverriding 'virtual void ' c++ errorWhy must we declare virtual methods as suchWhat are the new features in C++17?

Is it ethical to give a final exam after the professor has quit before teaching the remaining chapters of the course?

What does an IRS interview request entail when called in to verify expenses for a sole proprietor small business?

2001: A Space Odyssey's use of the song "Daisy Bell" (Bicycle Built for Two); life imitates art or vice-versa?

How discoverable are IPv6 addresses and AAAA names by potential attackers?

51k Euros annually for a family of 4 in Berlin: Is it enough?

Use BFD on a Virtual-Template Interface

How come Sam didn't become Lord of Horn Hill?

The logistics of corpse disposal

What is the meaning of the new sigil in Game of Thrones Season 8 intro?

What is Arya's weapon design?

Should I use a zero-interest credit card for a large one-time purchase?

List of Python versions

Identify plant with long narrow paired leaves and reddish stems

How to tell that you are a giant?

Identifying polygons that intersect with another layer using QGIS?

Should I discuss the type of campaign with my players?

porting install scripts : can rpm replace apt?

In predicate logic, does existential quantification (∃) include universal quantification (∀), i.e. can 'some' imply 'all'?

How does the particle を relate to the verb 行く in the structure「A を + B に行く」?

Why aren't air breathing engines used as small first stages

Why is "Consequences inflicted." not a sentence?

Align equal signs while including text over equalities

Is there a program I can run on the C64 to speed up booting of a game?

Can an alien society believe that their star system is the universe?



Overriding an object in memory with placement new



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!
Should we burninate the [wrap] tag?What uses are there for “placement new”?Method of derived class needs to downcast its parameterC++11 introduced a standardized memory model. What does it mean? And how is it going to affect C++ programming?Overloading >> operator for a base classChoice for class designWhy should I use a pointer rather than the object itself?Copying Objects and its data members to another objectoverriding 'virtual void ' c++ errorWhy must we declare virtual methods as suchWhat are the new features in C++17?



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








12















I have an object which I want to 'transform' into another object. For this I am using a placement new on the first object which creates a new object of the other type on top of its own address.



Consider the following code:



#include <string>
#include <iostream>

class Animal
public:
virtual void voice() = 0;
virtual void transform(void *animal) = 0;
virtual ~Animal() = default;;
;

class Cat : public Animal
public:
std::string name = "CAT";
void voice() override
std::cout << "MEOW I am a " << name << std::endl;

void transform(void *animal) override

;

class Dog : public Animal
public:
std::string name = "DOG";
void voice() override
std::cout << "WOOF I am a " << name << std::endl;

void transform(void *animal) override
new(animal) Cat();

;


You can see that when a Dog is called with transform it creates a new Cat on top of the given address.

Next, I will call the Dog::transform with its own address:



#include <iostream>
#include "Animals.h"

int main()
Cat cat;
Dog dog;
std::cout << "Cat says: ";
cat.voice() ;
std::cout << "Dog says: ";
dog.voice();
dog.transform(&dog);
std::cout << "Dog says: ";
dog.voice();
std::cout << "Dog address says: ";
(&dog)->voice();
return 0;



The results of this is:



Cat says: MEOW I am a CAT
Dog says: WOOF I am a DOG
Dog says: WOOF I am a CAT
Dog address says: MEOW I am a CAT


My questions are:



  1. Is this operation considered safe, or does it leave the object in unstable state?

  2. After the transform I call dog.voice(). It correctly prints the name CAT (it is now a cat), but still writes WOOF I am a, even though I would have thought that it should call the Cat's voice method? (You can see is that I call the same method but by the address ((&dog)->voice()), everything is working properly.









share|improve this question



















  • 6





    I can't cite where in the standard it says that this isn't allowed, but I can say that I get "WOOF I am a CAT" in both of the bottom lines on my system, which is a pretty good indicator that this behavior is not portable.

    – Silvio Mayolo
    8 hours ago











  • If you need this behavior which I would describe as "The object will appear to change it's class", consider using the Gang of Four State Pattern: en.wikipedia.org/wiki/State_pattern

    – Reginald Blue
    6 hours ago

















12















I have an object which I want to 'transform' into another object. For this I am using a placement new on the first object which creates a new object of the other type on top of its own address.



Consider the following code:



#include <string>
#include <iostream>

class Animal
public:
virtual void voice() = 0;
virtual void transform(void *animal) = 0;
virtual ~Animal() = default;;
;

class Cat : public Animal
public:
std::string name = "CAT";
void voice() override
std::cout << "MEOW I am a " << name << std::endl;

void transform(void *animal) override

;

class Dog : public Animal
public:
std::string name = "DOG";
void voice() override
std::cout << "WOOF I am a " << name << std::endl;

void transform(void *animal) override
new(animal) Cat();

;


You can see that when a Dog is called with transform it creates a new Cat on top of the given address.

Next, I will call the Dog::transform with its own address:



#include <iostream>
#include "Animals.h"

int main()
Cat cat;
Dog dog;
std::cout << "Cat says: ";
cat.voice() ;
std::cout << "Dog says: ";
dog.voice();
dog.transform(&dog);
std::cout << "Dog says: ";
dog.voice();
std::cout << "Dog address says: ";
(&dog)->voice();
return 0;



The results of this is:



Cat says: MEOW I am a CAT
Dog says: WOOF I am a DOG
Dog says: WOOF I am a CAT
Dog address says: MEOW I am a CAT


My questions are:



  1. Is this operation considered safe, or does it leave the object in unstable state?

  2. After the transform I call dog.voice(). It correctly prints the name CAT (it is now a cat), but still writes WOOF I am a, even though I would have thought that it should call the Cat's voice method? (You can see is that I call the same method but by the address ((&dog)->voice()), everything is working properly.









share|improve this question



















  • 6





    I can't cite where in the standard it says that this isn't allowed, but I can say that I get "WOOF I am a CAT" in both of the bottom lines on my system, which is a pretty good indicator that this behavior is not portable.

    – Silvio Mayolo
    8 hours ago











  • If you need this behavior which I would describe as "The object will appear to change it's class", consider using the Gang of Four State Pattern: en.wikipedia.org/wiki/State_pattern

    – Reginald Blue
    6 hours ago













12












12








12


1






I have an object which I want to 'transform' into another object. For this I am using a placement new on the first object which creates a new object of the other type on top of its own address.



Consider the following code:



#include <string>
#include <iostream>

class Animal
public:
virtual void voice() = 0;
virtual void transform(void *animal) = 0;
virtual ~Animal() = default;;
;

class Cat : public Animal
public:
std::string name = "CAT";
void voice() override
std::cout << "MEOW I am a " << name << std::endl;

void transform(void *animal) override

;

class Dog : public Animal
public:
std::string name = "DOG";
void voice() override
std::cout << "WOOF I am a " << name << std::endl;

void transform(void *animal) override
new(animal) Cat();

;


You can see that when a Dog is called with transform it creates a new Cat on top of the given address.

Next, I will call the Dog::transform with its own address:



#include <iostream>
#include "Animals.h"

int main()
Cat cat;
Dog dog;
std::cout << "Cat says: ";
cat.voice() ;
std::cout << "Dog says: ";
dog.voice();
dog.transform(&dog);
std::cout << "Dog says: ";
dog.voice();
std::cout << "Dog address says: ";
(&dog)->voice();
return 0;



The results of this is:



Cat says: MEOW I am a CAT
Dog says: WOOF I am a DOG
Dog says: WOOF I am a CAT
Dog address says: MEOW I am a CAT


My questions are:



  1. Is this operation considered safe, or does it leave the object in unstable state?

  2. After the transform I call dog.voice(). It correctly prints the name CAT (it is now a cat), but still writes WOOF I am a, even though I would have thought that it should call the Cat's voice method? (You can see is that I call the same method but by the address ((&dog)->voice()), everything is working properly.









share|improve this question
















I have an object which I want to 'transform' into another object. For this I am using a placement new on the first object which creates a new object of the other type on top of its own address.



Consider the following code:



#include <string>
#include <iostream>

class Animal
public:
virtual void voice() = 0;
virtual void transform(void *animal) = 0;
virtual ~Animal() = default;;
;

class Cat : public Animal
public:
std::string name = "CAT";
void voice() override
std::cout << "MEOW I am a " << name << std::endl;

void transform(void *animal) override

;

class Dog : public Animal
public:
std::string name = "DOG";
void voice() override
std::cout << "WOOF I am a " << name << std::endl;

void transform(void *animal) override
new(animal) Cat();

;


You can see that when a Dog is called with transform it creates a new Cat on top of the given address.

Next, I will call the Dog::transform with its own address:



#include <iostream>
#include "Animals.h"

int main()
Cat cat;
Dog dog;
std::cout << "Cat says: ";
cat.voice() ;
std::cout << "Dog says: ";
dog.voice();
dog.transform(&dog);
std::cout << "Dog says: ";
dog.voice();
std::cout << "Dog address says: ";
(&dog)->voice();
return 0;



The results of this is:



Cat says: MEOW I am a CAT
Dog says: WOOF I am a DOG
Dog says: WOOF I am a CAT
Dog address says: MEOW I am a CAT


My questions are:



  1. Is this operation considered safe, or does it leave the object in unstable state?

  2. After the transform I call dog.voice(). It correctly prints the name CAT (it is now a cat), but still writes WOOF I am a, even though I would have thought that it should call the Cat's voice method? (You can see is that I call the same method but by the address ((&dog)->voice()), everything is working properly.






c++ placement-new






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 hours ago









John Kugelman

249k54407460




249k54407460










asked 8 hours ago









Guy YafeGuy Yafe

4431416




4431416







  • 6





    I can't cite where in the standard it says that this isn't allowed, but I can say that I get "WOOF I am a CAT" in both of the bottom lines on my system, which is a pretty good indicator that this behavior is not portable.

    – Silvio Mayolo
    8 hours ago











  • If you need this behavior which I would describe as "The object will appear to change it's class", consider using the Gang of Four State Pattern: en.wikipedia.org/wiki/State_pattern

    – Reginald Blue
    6 hours ago












  • 6





    I can't cite where in the standard it says that this isn't allowed, but I can say that I get "WOOF I am a CAT" in both of the bottom lines on my system, which is a pretty good indicator that this behavior is not portable.

    – Silvio Mayolo
    8 hours ago











  • If you need this behavior which I would describe as "The object will appear to change it's class", consider using the Gang of Four State Pattern: en.wikipedia.org/wiki/State_pattern

    – Reginald Blue
    6 hours ago







6




6





I can't cite where in the standard it says that this isn't allowed, but I can say that I get "WOOF I am a CAT" in both of the bottom lines on my system, which is a pretty good indicator that this behavior is not portable.

– Silvio Mayolo
8 hours ago





I can't cite where in the standard it says that this isn't allowed, but I can say that I get "WOOF I am a CAT" in both of the bottom lines on my system, which is a pretty good indicator that this behavior is not portable.

– Silvio Mayolo
8 hours ago













If you need this behavior which I would describe as "The object will appear to change it's class", consider using the Gang of Four State Pattern: en.wikipedia.org/wiki/State_pattern

– Reginald Blue
6 hours ago





If you need this behavior which I would describe as "The object will appear to change it's class", consider using the Gang of Four State Pattern: en.wikipedia.org/wiki/State_pattern

– Reginald Blue
6 hours ago












3 Answers
3






active

oldest

votes


















10















Does this operation considered safe, or does it leave the object in unstable state?




This operation is not safe and causes undefined behavior. Cat and Dog have non trivial destructors so before you can reuse the storage cat and dog have you have to call their destructor so the previous object is cleaned up correctly.




After the transform I call dog.voice(). I prints correctly the CAT name (it is now a cat), but still writes WOOF I am a, even tough I would have thought that it should call the Cat's voice method? (You can see is that I call the same method but by the address ((&dog)->voice()), everything is working properly.




Using dog.voice(); after dog.transform(&dog); is undefined behavior. Since you've reused its storage without destroying it, you have undefined behavior. Lets say you do destroy dog in transform to get rid of that bit of undefined behavior you still aren't out of the woods. Using dog after it has been destroyed is undefined behavior. What you would have to do is capture the pointer placement new returns and use that pointer from then on. You could also use std::launder on dog with a reinterpret_cast to the type you transformed it to but it's not worth since you lose all encapsulation.




You also need to make sure when using placement new that the object you are using is large enough for the object you are constructing. In this case it should be since the classes are the same but a static_assert comparing the sizes will guarantee that and stop the compilation if it is not true.






share|improve this answer
































    4














    You have at least three issues with this code:



    • There is no guarantee that when placement new is called the size of the object you are constructing your new object in is sufficient to hold the new object

    • You are not calling destructor of the object used as a placeholder

    • You use the Dog object after it's storage has been reused.





    share|improve this answer






























      4














      1) No, this is not safe for the following reasons:



      • The behavior is undefined and can be different for some compilers.

      • The allocated memory needs to be big enough to hold the newly created structure.

      • Some compilers might call the destructor of the original object even if it is virtual, which would lead to leaks and crashes.

      • In your code, the destructor of the original object is not called, so it can lead to memory leaks.

      2) I observed on MSVC2015 that dog.voice() will call Dog::voice without checking the actual virtual table. In the second case, it checks the virtual table, which has been modified to be Cat::voice. However, as experienced by other users, some other compiler might perform some optimizations and directly call the method that matches the declaration in all cases.






      share|improve this answer

























      • When you say behavior is not portable you need to explain why. The destructor is already virtual.

        – SergeyA
        8 hours ago












      • I meant that some compilers do not behave the same. "Undefined behavior" might be better. I'll edit the answer.

        – Gilles-Philippe Paillé
        8 hours ago











      • Do note there is a virtual destructor in the code in question

        – NathanOliver
        8 hours ago












      • @NathanOliver That's true. I was mentioning general rules that needs to be respected. I will make it clearer.

        – Gilles-Philippe Paillé
        8 hours ago











      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%2f55711220%2foverriding-an-object-in-memory-with-placement-new%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      10















      Does this operation considered safe, or does it leave the object in unstable state?




      This operation is not safe and causes undefined behavior. Cat and Dog have non trivial destructors so before you can reuse the storage cat and dog have you have to call their destructor so the previous object is cleaned up correctly.




      After the transform I call dog.voice(). I prints correctly the CAT name (it is now a cat), but still writes WOOF I am a, even tough I would have thought that it should call the Cat's voice method? (You can see is that I call the same method but by the address ((&dog)->voice()), everything is working properly.




      Using dog.voice(); after dog.transform(&dog); is undefined behavior. Since you've reused its storage without destroying it, you have undefined behavior. Lets say you do destroy dog in transform to get rid of that bit of undefined behavior you still aren't out of the woods. Using dog after it has been destroyed is undefined behavior. What you would have to do is capture the pointer placement new returns and use that pointer from then on. You could also use std::launder on dog with a reinterpret_cast to the type you transformed it to but it's not worth since you lose all encapsulation.




      You also need to make sure when using placement new that the object you are using is large enough for the object you are constructing. In this case it should be since the classes are the same but a static_assert comparing the sizes will guarantee that and stop the compilation if it is not true.






      share|improve this answer





























        10















        Does this operation considered safe, or does it leave the object in unstable state?




        This operation is not safe and causes undefined behavior. Cat and Dog have non trivial destructors so before you can reuse the storage cat and dog have you have to call their destructor so the previous object is cleaned up correctly.




        After the transform I call dog.voice(). I prints correctly the CAT name (it is now a cat), but still writes WOOF I am a, even tough I would have thought that it should call the Cat's voice method? (You can see is that I call the same method but by the address ((&dog)->voice()), everything is working properly.




        Using dog.voice(); after dog.transform(&dog); is undefined behavior. Since you've reused its storage without destroying it, you have undefined behavior. Lets say you do destroy dog in transform to get rid of that bit of undefined behavior you still aren't out of the woods. Using dog after it has been destroyed is undefined behavior. What you would have to do is capture the pointer placement new returns and use that pointer from then on. You could also use std::launder on dog with a reinterpret_cast to the type you transformed it to but it's not worth since you lose all encapsulation.




        You also need to make sure when using placement new that the object you are using is large enough for the object you are constructing. In this case it should be since the classes are the same but a static_assert comparing the sizes will guarantee that and stop the compilation if it is not true.






        share|improve this answer



























          10












          10








          10








          Does this operation considered safe, or does it leave the object in unstable state?




          This operation is not safe and causes undefined behavior. Cat and Dog have non trivial destructors so before you can reuse the storage cat and dog have you have to call their destructor so the previous object is cleaned up correctly.




          After the transform I call dog.voice(). I prints correctly the CAT name (it is now a cat), but still writes WOOF I am a, even tough I would have thought that it should call the Cat's voice method? (You can see is that I call the same method but by the address ((&dog)->voice()), everything is working properly.




          Using dog.voice(); after dog.transform(&dog); is undefined behavior. Since you've reused its storage without destroying it, you have undefined behavior. Lets say you do destroy dog in transform to get rid of that bit of undefined behavior you still aren't out of the woods. Using dog after it has been destroyed is undefined behavior. What you would have to do is capture the pointer placement new returns and use that pointer from then on. You could also use std::launder on dog with a reinterpret_cast to the type you transformed it to but it's not worth since you lose all encapsulation.




          You also need to make sure when using placement new that the object you are using is large enough for the object you are constructing. In this case it should be since the classes are the same but a static_assert comparing the sizes will guarantee that and stop the compilation if it is not true.






          share|improve this answer
















          Does this operation considered safe, or does it leave the object in unstable state?




          This operation is not safe and causes undefined behavior. Cat and Dog have non trivial destructors so before you can reuse the storage cat and dog have you have to call their destructor so the previous object is cleaned up correctly.




          After the transform I call dog.voice(). I prints correctly the CAT name (it is now a cat), but still writes WOOF I am a, even tough I would have thought that it should call the Cat's voice method? (You can see is that I call the same method but by the address ((&dog)->voice()), everything is working properly.




          Using dog.voice(); after dog.transform(&dog); is undefined behavior. Since you've reused its storage without destroying it, you have undefined behavior. Lets say you do destroy dog in transform to get rid of that bit of undefined behavior you still aren't out of the woods. Using dog after it has been destroyed is undefined behavior. What you would have to do is capture the pointer placement new returns and use that pointer from then on. You could also use std::launder on dog with a reinterpret_cast to the type you transformed it to but it's not worth since you lose all encapsulation.




          You also need to make sure when using placement new that the object you are using is large enough for the object you are constructing. In this case it should be since the classes are the same but a static_assert comparing the sizes will guarantee that and stop the compilation if it is not true.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 3 hours ago









          John Kugelman

          249k54407460




          249k54407460










          answered 8 hours ago









          NathanOliverNathanOliver

          99.1k16138219




          99.1k16138219























              4














              You have at least three issues with this code:



              • There is no guarantee that when placement new is called the size of the object you are constructing your new object in is sufficient to hold the new object

              • You are not calling destructor of the object used as a placeholder

              • You use the Dog object after it's storage has been reused.





              share|improve this answer



























                4














                You have at least three issues with this code:



                • There is no guarantee that when placement new is called the size of the object you are constructing your new object in is sufficient to hold the new object

                • You are not calling destructor of the object used as a placeholder

                • You use the Dog object after it's storage has been reused.





                share|improve this answer

























                  4












                  4








                  4







                  You have at least three issues with this code:



                  • There is no guarantee that when placement new is called the size of the object you are constructing your new object in is sufficient to hold the new object

                  • You are not calling destructor of the object used as a placeholder

                  • You use the Dog object after it's storage has been reused.





                  share|improve this answer













                  You have at least three issues with this code:



                  • There is no guarantee that when placement new is called the size of the object you are constructing your new object in is sufficient to hold the new object

                  • You are not calling destructor of the object used as a placeholder

                  • You use the Dog object after it's storage has been reused.






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 8 hours ago









                  SergeyASergeyA

                  45.2k53990




                  45.2k53990





















                      4














                      1) No, this is not safe for the following reasons:



                      • The behavior is undefined and can be different for some compilers.

                      • The allocated memory needs to be big enough to hold the newly created structure.

                      • Some compilers might call the destructor of the original object even if it is virtual, which would lead to leaks and crashes.

                      • In your code, the destructor of the original object is not called, so it can lead to memory leaks.

                      2) I observed on MSVC2015 that dog.voice() will call Dog::voice without checking the actual virtual table. In the second case, it checks the virtual table, which has been modified to be Cat::voice. However, as experienced by other users, some other compiler might perform some optimizations and directly call the method that matches the declaration in all cases.






                      share|improve this answer

























                      • When you say behavior is not portable you need to explain why. The destructor is already virtual.

                        – SergeyA
                        8 hours ago












                      • I meant that some compilers do not behave the same. "Undefined behavior" might be better. I'll edit the answer.

                        – Gilles-Philippe Paillé
                        8 hours ago











                      • Do note there is a virtual destructor in the code in question

                        – NathanOliver
                        8 hours ago












                      • @NathanOliver That's true. I was mentioning general rules that needs to be respected. I will make it clearer.

                        – Gilles-Philippe Paillé
                        8 hours ago















                      4














                      1) No, this is not safe for the following reasons:



                      • The behavior is undefined and can be different for some compilers.

                      • The allocated memory needs to be big enough to hold the newly created structure.

                      • Some compilers might call the destructor of the original object even if it is virtual, which would lead to leaks and crashes.

                      • In your code, the destructor of the original object is not called, so it can lead to memory leaks.

                      2) I observed on MSVC2015 that dog.voice() will call Dog::voice without checking the actual virtual table. In the second case, it checks the virtual table, which has been modified to be Cat::voice. However, as experienced by other users, some other compiler might perform some optimizations and directly call the method that matches the declaration in all cases.






                      share|improve this answer

























                      • When you say behavior is not portable you need to explain why. The destructor is already virtual.

                        – SergeyA
                        8 hours ago












                      • I meant that some compilers do not behave the same. "Undefined behavior" might be better. I'll edit the answer.

                        – Gilles-Philippe Paillé
                        8 hours ago











                      • Do note there is a virtual destructor in the code in question

                        – NathanOliver
                        8 hours ago












                      • @NathanOliver That's true. I was mentioning general rules that needs to be respected. I will make it clearer.

                        – Gilles-Philippe Paillé
                        8 hours ago













                      4












                      4








                      4







                      1) No, this is not safe for the following reasons:



                      • The behavior is undefined and can be different for some compilers.

                      • The allocated memory needs to be big enough to hold the newly created structure.

                      • Some compilers might call the destructor of the original object even if it is virtual, which would lead to leaks and crashes.

                      • In your code, the destructor of the original object is not called, so it can lead to memory leaks.

                      2) I observed on MSVC2015 that dog.voice() will call Dog::voice without checking the actual virtual table. In the second case, it checks the virtual table, which has been modified to be Cat::voice. However, as experienced by other users, some other compiler might perform some optimizations and directly call the method that matches the declaration in all cases.






                      share|improve this answer















                      1) No, this is not safe for the following reasons:



                      • The behavior is undefined and can be different for some compilers.

                      • The allocated memory needs to be big enough to hold the newly created structure.

                      • Some compilers might call the destructor of the original object even if it is virtual, which would lead to leaks and crashes.

                      • In your code, the destructor of the original object is not called, so it can lead to memory leaks.

                      2) I observed on MSVC2015 that dog.voice() will call Dog::voice without checking the actual virtual table. In the second case, it checks the virtual table, which has been modified to be Cat::voice. However, as experienced by other users, some other compiler might perform some optimizations and directly call the method that matches the declaration in all cases.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited 4 hours ago

























                      answered 8 hours ago









                      Gilles-Philippe PailléGilles-Philippe Paillé

                      56210




                      56210












                      • When you say behavior is not portable you need to explain why. The destructor is already virtual.

                        – SergeyA
                        8 hours ago












                      • I meant that some compilers do not behave the same. "Undefined behavior" might be better. I'll edit the answer.

                        – Gilles-Philippe Paillé
                        8 hours ago











                      • Do note there is a virtual destructor in the code in question

                        – NathanOliver
                        8 hours ago












                      • @NathanOliver That's true. I was mentioning general rules that needs to be respected. I will make it clearer.

                        – Gilles-Philippe Paillé
                        8 hours ago

















                      • When you say behavior is not portable you need to explain why. The destructor is already virtual.

                        – SergeyA
                        8 hours ago












                      • I meant that some compilers do not behave the same. "Undefined behavior" might be better. I'll edit the answer.

                        – Gilles-Philippe Paillé
                        8 hours ago











                      • Do note there is a virtual destructor in the code in question

                        – NathanOliver
                        8 hours ago












                      • @NathanOliver That's true. I was mentioning general rules that needs to be respected. I will make it clearer.

                        – Gilles-Philippe Paillé
                        8 hours ago
















                      When you say behavior is not portable you need to explain why. The destructor is already virtual.

                      – SergeyA
                      8 hours ago






                      When you say behavior is not portable you need to explain why. The destructor is already virtual.

                      – SergeyA
                      8 hours ago














                      I meant that some compilers do not behave the same. "Undefined behavior" might be better. I'll edit the answer.

                      – Gilles-Philippe Paillé
                      8 hours ago





                      I meant that some compilers do not behave the same. "Undefined behavior" might be better. I'll edit the answer.

                      – Gilles-Philippe Paillé
                      8 hours ago













                      Do note there is a virtual destructor in the code in question

                      – NathanOliver
                      8 hours ago






                      Do note there is a virtual destructor in the code in question

                      – NathanOliver
                      8 hours ago














                      @NathanOliver That's true. I was mentioning general rules that needs to be respected. I will make it clearer.

                      – Gilles-Philippe Paillé
                      8 hours ago





                      @NathanOliver That's true. I was mentioning general rules that needs to be respected. I will make it clearer.

                      – Gilles-Philippe Paillé
                      8 hours ago

















                      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%2f55711220%2foverriding-an-object-in-memory-with-placement-new%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

                      Are there any comparative studies done between Ashtavakra Gita and Buddhim?How is it wrong to believe that a self exists, or that it doesn't?Can you criticise or improve Ven. Bodhi's description of MahayanaWas the doctrine of 'Anatta', accepted as doctrine by modern Buddhism, actually taught by the Buddha?Relationship between Buddhism, Hinduism and Yoga?Comparison of Nirvana, Tao and Brahman/AtmaIs there a distinction between “ego identity” and “craving/hating”?Are there many differences between Taoism and Buddhism?Loss of “faith” in buddhismSimilarity between creation in Abrahamic religions and beginning of life in Earth mentioned Agganna Sutta?Are there studies about the difference between meditating in the morning versus in the evening?Can one follow Hinduism and Buddhism at the same time?Are there any prohibitions on participating in other religion's practices?Psychology of 'flow'

                      Where else does the Shulchan Aruch quote an authority by name?Parashat Metzora+HagadolPesach/PassoverShulchan Aruch UTF-8Anonymous glosses in the Shulchan AruchWhy is the Shulchan Aruch definitive?Siman 32, Kitzur Shulchan Aruch: UntranslatedLitvaks/Yeshivish and Shulchan AruchBuying a Shulchan AruchEnglish version of SHULCHAN ARUCHIs there any place where Shulchan Aruch rules with the Rosh against the Rif and Rambam?Are there practices where Sepharadim do not hold by Shulchan Aruch?5th part of the shulchan aruch

                      fallocate: fallocate failed: Text file busy in Ubuntu 17.04? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)defragmenting and increasing performance of old lubuntu system with swap partitionIssue with increasing the root partition from the swapthis /usr/bin/dpkg returned error || ubuntu-16.04, 64bitDefault 17.04 swap file locationHow to Resize Ubuntu 17.04 Zesty Swap file size?Ubuntu freezes from online formsMy Laptop is not starting after upgrade ubuntu 16.04 (Kernel 4.8.0-38 to 04.10.0-36)hcp: ERROR: FALLOCATE FAILED!Not sure my swap is being usedWine 3.0 asking for more virtual free swap