Completely Deleting Pointers

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Min

    Completely Deleting Pointers

    CFool
    {
    public:
    void StartWorldWarII I() { /*** Launch Nuclear Missiles **/ }
    };

    int main()
    {
    CFool* pFool = new CFool();
    delete pFool;
    //////******* const unsigned int GARBAGE = 0xA3;
    ///// ******* memset( pFoo, GARBAGE , sizeof( CFool) );
    pFool->StartWorldWarI II();

    return 0;
    }

    Among other techniques from Writing Solid Code by Steve Maguire, I tried to
    scramble the content by filling garbages ( the commented lines ). But it
    does not guarantee that "pFoo->StartWorldWarI II()" will crash, but the
    object will output garbage, the next time it is used. (an obvious attempt
    to indicate that the instance has been deleted.)

    Anyway, Anybody knows any trick or technique to guarantee
    "pFoo->StartWorldWarI II()" will crash ? for debugging purpose.
    (I have a feeling that I am asking it in a wrong NG, but what the heck.)

    TIA


  • Haplo

    #2
    Re: Completely Deleting Pointers

    In article <eR_La.327039$r o6.7900519@news 2.calgary.shaw. ca>,
    nobody@home.com says...[color=blue]
    > CFool
    > {
    > public:
    > void StartWorldWarII I() { /*** Launch Nuclear Missiles **/ }
    > };
    >
    > int main()
    > {
    > CFool* pFool = new CFool();
    > delete pFool;
    > //////******* const unsigned int GARBAGE = 0xA3;
    > ///// ******* memset( pFoo, GARBAGE , sizeof( CFool) );
    > pFool->StartWorldWarI II();
    >
    > return 0;
    > }
    >
    > Among other techniques from Writing Solid Code by Steve Maguire, I tried to
    > scramble the content by filling garbages ( the commented lines ). But it
    > does not guarantee that "pFoo->StartWorldWarI II()" will crash, but the
    > object will output garbage, the next time it is used. (an obvious attempt
    > to indicate that the instance has been deleted.)
    >
    > Anyway, Anybody knows any trick or technique to guarantee
    > "pFoo->StartWorldWarI II()" will crash ? for debugging purpose.
    > (I have a feeling that I am asking it in a wrong NG, but what the heck.)[/color]

    How about

    pFool = NULL;

    after you delete it ?


    Haplo

    Comment

    • Andre Kostur

      #3
      Re: Completely Deleting Pointers

      Haplo <Wim.Valgaeren@ p.b> wrote in
      news:MPG.196a9c b8986adf9198968 5@news.telenet. be:
      [color=blue]
      > In article <eR_La.327039$r o6.7900519@news 2.calgary.shaw. ca>,
      > nobody@home.com says...[color=green]
      >> CFool
      >> {
      >> public:
      >> void StartWorldWarII I() { /*** Launch Nuclear Missiles
      >> **/ }
      >> };
      >>
      >> int main()
      >> {
      >> CFool* pFool = new CFool();
      >> delete pFool;
      >> //////******* const unsigned int GARBAGE = 0xA3;
      >> ///// ******* memset( pFoo, GARBAGE , sizeof( CFool) );
      >> pFool->StartWorldWarI II();
      >>
      >> return 0;
      >> }
      >>
      >> Among other techniques from Writing Solid Code by Steve Maguire, I
      >> tried to scramble the content by filling garbages ( the commented
      >> lines ). But it does not guarantee that "pFoo->StartWorldWarI II()"
      >> will crash, but the object will output garbage, the next time it is
      >> used. (an obvious attempt to indicate that the instance has been
      >> deleted.)
      >>
      >> Anyway, Anybody knows any trick or technique to guarantee
      >> "pFoo->StartWorldWarI II()" will crash ? for debugging purpose.
      >> (I have a feeling that I am asking it in a wrong NG, but what the
      >> heck.)[/color]
      >
      > How about
      >
      > pFool = NULL;
      >
      > after you delete it ?[/color]

      That doesn't guarantee a crash. That invokes "Undefined Behaviour",
      which might include a crash (then again, it might do nothing. I know of
      at least one implementation where the above code will function perfectly
      fine, if StartWorldWarII I doesn't reference any class members....)

      To the OP, you might want to implement your own smart pointer which will
      call something like abort() or terminate() if one attempts to dereference
      a NULL pointer.

      Comment

      • Julián Albo

        #4
        Re: Completely Deleting Pointers

        Min escribió:
        [color=blue]
        > int main()
        > {
        > CFool* pFool = new CFool();
        > delete pFool;
        > //////******* const unsigned int GARBAGE = 0xA3;
        > ///// ******* memset( pFoo, GARBAGE , sizeof( CFool) );
        > pFool->StartWorldWarI II();
        >
        > return 0;
        > }
        >
        > Among other techniques from Writing Solid Code by Steve Maguire, I tried to
        > scramble the content by filling garbages ( the commented lines ). But it[/color]

        I read that book, and it clearly explains that you must not use memory
        you have freed. You must not put garbage after delete it.

        Regards.

        Comment

        • Min

          #5
          Re: Completely Deleting Pointers

          Sorry, there is more clarification.

          delete pFool;
          //////******* const unsigned int GARBAGE = 0xA3;
          ///// ******* memset( pFoo, GARBAGE , sizeof( CFool) );

          should be read as
          //////******* const unsigned int GARBAGE = 0xA3;
          ///// ******* memset( pFoo, GARBAGE , sizeof( CFool) );
          delete pFool;

          Of course, "pFool = NULL;" could partially solve the problem. But failure
          to do so won't. Consider this:

          //******** Code Begins *************** ***
          CFool* pSaddam = new CFool();
          CFool* pUday = pSaddam;

          //////******* const unsigned int GARBAGE = 0xA3;
          ///// ******* memset( pSaddam, GARBAGE , sizeof( CFool) );
          delete pSaddam;
          pSaddam = NULL;

          pUday->StartWorldWarI II();

          //*************** *************** ******
          It is very obvious in this example. But what I am trying to accomplish is
          than even forgetting to set to NULL, any pointers still pointing to an
          invalid memory block will gurantee to crash, if it is used again after
          deletion. By scrambling pSaddam before deletion, pUday might not do things
          properly, but it is still doing something, instread of plain crashing.


          Comment

          • Julián Albo

            #6
            Re: Completely Deleting Pointers

            Min escribió:
            [color=blue]
            > Sorry, there is more clarification.
            >
            > delete pFool;
            > //////******* const unsigned int GARBAGE = 0xA3;
            > ///// ******* memset( pFoo, GARBAGE , sizeof( CFool) );
            >
            > should be read as
            > //////******* const unsigned int GARBAGE = 0xA3;
            > ///// ******* memset( pFoo, GARBAGE , sizeof( CFool) );
            > delete pFool;[/color]

            That way the destructor of the object pointed by pFool will probably
            crash. I think the only safe mode to put garbage in the memory used by
            the object is overloading operator new and operator delete.

            Regards.

            Comment

            • Ron Samuel Klatchko

              #7
              Re: Completely Deleting Pointers

              One problem you have with this is once the memory is freed, that
              memory is up for grabs. So even if you do something that 'guarantees'
              a crash, once that memory is allocated again, the memory contents will
              get changed.

              So, the first thing to note is that if you want a true guarantee, you
              can't actually free it. Now this means that you will have a memory
              leak. If this is an object that gets allocated constantly, then you
              are probably SOL. But if these objects are only created rarely, you
              might be fine.

              And also to note, this means that objects that are put on the stack
              are beyond hope. Due to the way stacks work, there is no way to
              prevent the memory from being freed.

              So, with all those caveats, here is quickly thought out method. First
              create
              the base class death_on_delete :

              class death_on_delete
              {
              public:
              base() : deleted_(false) {}
              ~base() { deleted_ = true; }
              void operator delete(void *) { /* do nothing */ }
              void check() const { assert(deleted_ == false); }

              private:
              bool deleted_;
              };

              Any class that derives from this and is created on the heap will never
              truly go away. Again, this does not work for classes on the stack
              (nor for classes that override operator delete).

              Then, in all your methods, you need to add a call to
              death_on_delete ::check(). This method will assert if it is called
              after the function has been deleted.

              Have fun.

              samuel

              Comment

              Working...