Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. [SOLVED}stack vs. heap objects: how to destruct only heap ones?

[SOLVED}stack vs. heap objects: how to destruct only heap ones?

Scheduled Pinned Locked Moved C / C++ / MFC
visual-studiodockerdata-structurestutorialquestion
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    liquid_
    wrote on last edited by
    #1

    Suppose we have a class:

    class container
    {
    public:
    container(sometype *itp)
    {
    item = itp;
    }
    ~container();
    private:
    sometype *item;
    };

    It's possible to use the class object in these ways:

    void function()
    {
    sometype item;
    sometype *pitem;

    container ct1(&item);
    pitem = new sometype;
    container ct2(pitem);
    }

    I'd like to destroy sometype pointer in class's destructor provided it was created on the heap by new operator but not that on the stack. How to make it?

    Richard Andrew x64R A 2 Replies Last reply
    0
    • L liquid_

      Suppose we have a class:

      class container
      {
      public:
      container(sometype *itp)
      {
      item = itp;
      }
      ~container();
      private:
      sometype *item;
      };

      It's possible to use the class object in these ways:

      void function()
      {
      sometype item;
      sometype *pitem;

      container ct1(&item);
      pitem = new sometype;
      container ct2(pitem);
      }

      I'd like to destroy sometype pointer in class's destructor provided it was created on the heap by new operator but not that on the stack. How to make it?

      Richard Andrew x64R Offline
      Richard Andrew x64R Offline
      Richard Andrew x64
      wrote on last edited by
      #2

      There is no way to tell just by the variable itself, but you could provide a flag to the constructor to indicate the difference:

      class container
      {
      public:
      container(sometype *itp, bool HeapFlag)
      {
      item = itp;
      Flag = HeapFlag;
      }
      ~container();
      {
      if (Flag)
      delete item;
      }
      private:
      sometype *item;
      bool Flag;
      };

      The difficult we do right away... ...the impossible takes slightly longer.

      L 1 Reply Last reply
      0
      • L liquid_

        Suppose we have a class:

        class container
        {
        public:
        container(sometype *itp)
        {
        item = itp;
        }
        ~container();
        private:
        sometype *item;
        };

        It's possible to use the class object in these ways:

        void function()
        {
        sometype item;
        sometype *pitem;

        container ct1(&item);
        pitem = new sometype;
        container ct2(pitem);
        }

        I'd like to destroy sometype pointer in class's destructor provided it was created on the heap by new operator but not that on the stack. How to make it?

        A Offline
        A Offline
        Andre Kraak
        wrote on last edited by
        #3

        The best way to solve this is to build it into the constructor. Use a boolean with the constructor to specify whether the class should take ownership of the sometype and be responsible for destroying it.

        class container
        {
        public:
        container(sometype *itp, bool takeOwnership)
        {
        item = itp;
        owner = takeOwnership
        }
        ~container();
        private:
        sometype *item;
        bool owner;
        };

        void function()
        {
        sometype item;
        sometype *pitem;

        container ct1(&item, false);
        pitem = new sometype;
        container ct2(pitem, true);
        }

        1 Reply Last reply
        0
        • Richard Andrew x64R Richard Andrew x64

          There is no way to tell just by the variable itself, but you could provide a flag to the constructor to indicate the difference:

          class container
          {
          public:
          container(sometype *itp, bool HeapFlag)
          {
          item = itp;
          Flag = HeapFlag;
          }
          ~container();
          {
          if (Flag)
          delete item;
          }
          private:
          sometype *item;
          bool Flag;
          };

          The difficult we do right away... ...the impossible takes slightly longer.

          L Offline
          L Offline
          liquid_
          wrote on last edited by
          #4

          I think I've just found pretty good solution which, however, may not work well in multithreaded environment. Let's add a static variable bool heapcreated, a flag createdflag and overload operator new. That would look like this:

          class sometype
          {
          protected:
          static bool heapcreated;
          bool createdflag;
          public:
          sometype()
          {
          createdflag = heapcreated;
          heapcreated = false;
          }
          bool IsHeapCreated()
          {
          return createdflag;
          }
          void *operator new(size_t n)
          {
          sometype *stp=::new sometype;

            heapcreated = true;
            return stp;
          }
          

          class container
          {
          public:
          container(sometype *itp)
          {
          item = itp;
          }
          ~container();
          {
          if (item->IsHeapCreated())
          delete item;
          }
          private:
          sometype *item;
          };

          The new destructor of container would behave different depending on mode of sometype creation. I've searched this solution to be used when you build a library and you do not want a caller to have to do an overhead work adding a flag parameter. If you had to make many calls to container constructor with pointers to sometype it would be slightly difficult to save somewhere the pointers and then delete them. Also, you should be able to pass a pointer to stack variable which must not be deleted explicitly. It's a bit tricky but my simple test works.

          Richard Andrew x64R 1 Reply Last reply
          0
          • L liquid_

            I think I've just found pretty good solution which, however, may not work well in multithreaded environment. Let's add a static variable bool heapcreated, a flag createdflag and overload operator new. That would look like this:

            class sometype
            {
            protected:
            static bool heapcreated;
            bool createdflag;
            public:
            sometype()
            {
            createdflag = heapcreated;
            heapcreated = false;
            }
            bool IsHeapCreated()
            {
            return createdflag;
            }
            void *operator new(size_t n)
            {
            sometype *stp=::new sometype;

              heapcreated = true;
              return stp;
            }
            

            class container
            {
            public:
            container(sometype *itp)
            {
            item = itp;
            }
            ~container();
            {
            if (item->IsHeapCreated())
            delete item;
            }
            private:
            sometype *item;
            };

            The new destructor of container would behave different depending on mode of sometype creation. I've searched this solution to be used when you build a library and you do not want a caller to have to do an overhead work adding a flag parameter. If you had to make many calls to container constructor with pointers to sometype it would be slightly difficult to save somewhere the pointers and then delete them. Also, you should be able to pass a pointer to stack variable which must not be deleted explicitly. It's a bit tricky but my simple test works.

            Richard Andrew x64R Offline
            Richard Andrew x64R Offline
            Richard Andrew x64
            wrote on last edited by
            #5

            Good on you! That's a clever solution. :)

            The difficult we do right away... ...the impossible takes slightly longer.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups