Reusing a deleted pointer.

Discussion in 'C++' started by Alan, Dec 18, 2004.

  1. Alan

    Alan Guest

    Using VC++ (1998) compiler with PFE32 editor in Win2K Pro SP4.
    (DigitalMars CD on order. )

    The program (below) instantiates a class and then deletes it.
    I would have thought that reusing the deleted pointer would
    have caused an exception, but it does not - or my coding or
    thinking is incorrect?

    #include <iostream>
    using namespace std;

    class A {
    int a;
    public:
    A(): a(0) { cout << " A::A()" << endl; }
    ~A() { cout << "~A::A()" << endl << endl; }
    void print() { cout << "a = " << a << endl; }
    void set(const int& aa) { a=aa; print(); }
    };

    int main() {

    A* b = new A; // ptr
    A& c = *b; // ref

    b->set(10); // test ptr
    c.set(5); // test ref

    delete b;

    try {
    A& y = *b; // no problems!
    y.set(55); // causes system error (msg in Dos-box)
    } catch(...) { cout << "failed" << endl; exit(-1); }

    cout << "No failure" << endl; // always gets here

    return 0;
    }
     
    Alan, Dec 18, 2004
    #1
    1. Advertising

  2. Alan wrote:

    > Using VC++ (1998) compiler with PFE32 editor in Win2K Pro SP4.
    > (DigitalMars CD on order. )
    >
    > The program (below) instantiates a class and then deletes it.
    > I would have thought that reusing the deleted pointer would
    > have caused an exception, but it does not - or my coding or
    > thinking is incorrect?


    reusing a deleted pointer (or really any invalid pointer) simply causes
    'undefined behavior'. Now undefined behaviour 'could' result in an
    exception, the same way it 'could' result in your computer taking a trip
    to mars... but neither is really necessary and if it seems to work ok
    that could be attributed to undefined behavior as well.

    David
     
    David Lindauer, Dec 18, 2004
    #2
    1. Advertising

  3. Alan

    Jon Bell Guest

    In article <>,
    Alan <> wrote:
    >
    >The program (below) instantiates a class and then deletes it.
    >I would have thought that reusing the deleted pointer would
    >have caused an exception, but it does not - or my coding or
    >thinking is incorrect?


    Deleting a pointer simply tells the operating system that it is free to
    allocate the memory that it points to, for something else, whenever the OS
    feels it is necessary. It does not actually clear that memory, or change
    the pointer itself, because that would be a waste of CPU cycles in many
    situations.

    Therefore there is a good chance that you will actually be able to follow
    that pointer to whatever it originally pointed to, for some time
    thereafter... but you can't predict how long this will work.

    --
    Jon Bell <> Presbyterian College
    Dept. of Physics and Computer Science Clinton, South Carolina USA
     
    Jon Bell, Dec 18, 2004
    #3
  4. "Alan" <> wrote in message
    news:...
    > Using VC++ (1998) compiler with PFE32 editor in Win2K Pro SP4.
    > (DigitalMars CD on order. )
    >
    > The program (below) instantiates a class and then deletes it.
    > I would have thought that reusing the deleted pointer would
    > have caused an exception, but it does not - or my coding or
    > thinking is incorrect?
    >
    > #include <iostream>
    > using namespace std;
    >
    > class A {
    > int a;
    > public:
    > A(): a(0) { cout << " A::A()" << endl; }
    > ~A() { cout << "~A::A()" << endl << endl; }
    > void print() { cout << "a = " << a << endl; }
    > void set(const int& aa) { a=aa; print(); }
    > };
    >
    > int main() {
    >
    > A* b = new A; // ptr
    > A& c = *b; // ref
    >
    > b->set(10); // test ptr
    > c.set(5); // test ref
    >
    > delete b;
    >
    > try {
    > A& y = *b; // no problems!
    > y.set(55); // causes system error (msg in Dos-box)
    > } catch(...) { cout << "failed" << endl; exit(-1); }
    >
    > cout << "No failure" << endl; // always gets here
    >
    > return 0;
    > }


    To follow up on the other replies, if you look more carefully at the
    contents of the object "b" you
    will see ( at least on VC++6) that after deletion, the memory used by b is
    written over and the original
    value a is destroyed! I tinkered a bit with this program, if you do a few
    more allocations of A's, you
    will eventually find that an object is allocated at the same address as b,
    very nasty, now modifying b modifies
    some other unrelated object! . Just goes to show, just because you don't
    crash, all may not be well.

    By the way, your object is too simple to cause a crash, the original
    address of b would almost always point to to valid memory so deferencing it
    would not cause a crash after
    you delete it - just put some virtual functions in your class and try
    calling one of those after deletion and then
    you'll crash for sure..!

    dave
     
    Dave Townsend, Dec 18, 2004
    #4
  5. Alan

    Alan Guest

    "Dave Townsend" <> wrote in message news:...
    >
    > "Alan" <> wrote in message
    > news:...

    [snip]
    >
    > To follow up on the other replies, if you look more carefully at the
    > contents of the object "b" you
    > will see ( at least on VC++6) that after deletion, the memory used by b is
    > written over and the original
    > value a is destroyed! I tinkered a bit with this program, if you do a few
    > more allocations of A's, you
    > will eventually find that an object is allocated at the same address as b,
    > very nasty, now modifying b modifies
    > some other unrelated object! . Just goes to show, just because you don't
    > crash, all may not be well.
    >
    > By the way, your object is too simple to cause a crash, the original
    > address of b would almost always point to to valid memory so deferencing it
    > would not cause a crash after
    > you delete it - just put some virtual functions in your class and try
    > calling one of those after deletion and then
    > you'll crash for sure..!
    >
    > dave


    Thanks Dave, John and David.
     
    Alan, Dec 18, 2004
    #5
  6. Alan

    Alan Guest

    "Dave Townsend" <> wrote in message news:...
    >
    > "Alan" <> wrote in message
    > news:...

    [snip]
    > To follow up on the other replies, if you look more carefully at the
    > contents of the object "b" you
    > will see ( at least on VC++6) that after deletion, the memory used by b is
    > written over and the original
    > value a is destroyed! I tinkered a bit with this program, if you do a few
    > more allocations of A's, you
    > will eventually find that an object is allocated at the same address as b,
    > very nasty, now modifying b modifies
    > some other unrelated object! . Just goes to show, just because you don't
    > crash, all may not be well.
    >
    > By the way, your object is too simple to cause a crash, the original
    > address of b would almost always point to to valid memory so deferencing it
    > would not cause a crash after
    > you delete it - just put some virtual functions in your class and try
    > calling one of those after deletion and then
    > you'll crash for sure..!
    >
    > dave


    I've put a virtual function in but it didn't fail until I introduced a static
    variable into the class for instance counting. I've cut and cut the
    original program.. The code below (I'm using VC++6 too) succeeds
    or fails, per user choice. What puzzles me is why one class fails and
    the other doesn't - as the differences appear small.

    #include <iostream>
    using namespace std;

    class Failure {
    int a;
    static int count; // count instances, display them
    public:
    Failure(): a(0) { cout << "constructor " << count++ << endl; }
    ~Failure() { cout << "destructor " << --count << endl; }
    virtual void set(const int& aa) { a=aa; }
    };

    class Success {
    int a;
    static int count; // count instances, no display
    public:
    Success(): a(0) { count++; cout << "constructor ?" << endl; }
    ~Success() { --count; cout << "destructor ?" << endl; }
    virtual void set(const int& aa) { a=aa; }
    };

    int Failure::count = 1;
    int Success::count = 1;

    int main(int argc) {

    // no command line arguments (succeeds)
    if( argc == 1 )

    Success* s = new Success;
    delete s;
    cout << "class Success *s: try { s->set(1000) }" << endl;
    try {
    s->set(1000);
    } catch(...) { cout << "try failed" << endl; exit(-1); }
    }

    // one or more command line arguments (fails)
    else {
    Failure* f = new Failure;
    delete f;
    cout << "class Failure *f: try { f->set(1000) }" << endl;
    try {
    f->set(1000);
    } catch(...) { cout << "try failed" << endl; exit(-1); }
    }

    cout << "No failure" << endl;
    return 0;
    }

    Regards,
    Alan
     
    Alan, Dec 20, 2004
    #6
  7. Alan

    Alan Guest

    "Alan" <> wrote in message news:...
    >
    > "Dave Townsend" <> wrote in message news:...
    > >
    > > "Alan" <> wrote in message
    > > news:...

    > [snip]
    > > To follow up on the other replies, if you look more carefully at the
    > > contents of the object "b" you
    > > will see ( at least on VC++6) that after deletion, the memory used by b is
    > > written over and the original
    > > value a is destroyed! I tinkered a bit with this program, if you do a few
    > > more allocations of A's, you
    > > will eventually find that an object is allocated at the same address as b,
    > > very nasty, now modifying b modifies
    > > some other unrelated object! . Just goes to show, just because you don't
    > > crash, all may not be well.
    > >
    > > By the way, your object is too simple to cause a crash, the original
    > > address of b would almost always point to to valid memory so deferencing it
    > > would not cause a crash after
    > > you delete it - just put some virtual functions in your class and try
    > > calling one of those after deletion and then
    > > you'll crash for sure..!
    > >
    > > dave

    >
    > I've put a virtual function in but it didn't fail until I introduced a static
    > variable into the class for instance counting. I've cut and cut the
    > original program.. The code below (I'm using VC++6 too) succeeds
    > or fails, per user choice. What puzzles me is why one class fails and
    > the other doesn't - as the differences appear small.
    >
    > #include <iostream>
    > using namespace std;
    >
    > class Failure {
    > int a;
    > static int count; // count instances, display them
    > public:
    > Failure(): a(0) { cout << "constructor " << count++ << endl; }
    > ~Failure() { cout << "destructor " << --count << endl; }
    > virtual void set(const int& aa) { a=aa; }
    > };
    >
    > class Success {
    > int a;
    > static int count; // count instances, no display
    > public:
    > Success(): a(0) { count++; cout << "constructor ?" << endl; }
    > ~Success() { --count; cout << "destructor ?" << endl; }
    > virtual void set(const int& aa) { a=aa; }
    > };
    >
    > int Failure::count = 1;
    > int Success::count = 1;
    >
    > int main(int argc) {
    >
    > // no command line arguments (succeeds)
    > if( argc == 1 )
    >
    > Success* s = new Success;
    > delete s;
    > cout << "class Success *s: try { s->set(1000) }" << endl;
    > try {
    > s->set(1000);
    > } catch(...) { cout << "try failed" << endl; exit(-1); }
    > }
    >
    > // one or more command line arguments (fails)
    > else {
    > Failure* f = new Failure;
    > delete f;
    > cout << "class Failure *f: try { f->set(1000) }" << endl;
    > try {
    > f->set(1000);
    > } catch(...) { cout << "try failed" << endl; exit(-1); }
    > }
    >
    > cout << "No failure" << endl;
    > return 0;
    > }
    >
    > Regards,
    > Alan


    There is an opening brace missing after "if( argc == 1 )",
    should read "if(argc == 1) {"
    I can't explain it - it is there in the original file ;-)
     
    Alan, Dec 20, 2004
    #7
  8. Alan

    Tom Widmer Guest

    Alan wrote:
    > I've put a virtual function in but it didn't fail until I introduced

    a static
    > variable into the class for instance counting. I've cut and cut the
    > original program.. The code below (I'm using VC++6 too) succeeds
    > or fails, per user choice. What puzzles me is why one class fails and
    > the other doesn't - as the differences appear small.


    That's the nature of undefined behaviour. Understanding why it has a
    certain effect often requires intimite knowledge of the compiler and its
    optimizations. The policy is to *never* write any code that has
    undefined behaviour, since even if such code appears to work here and
    now, as soon as you demo the system to an investor, it will almost
    certainly crash.

    Tom
     
    Tom Widmer, Dec 20, 2004
    #8
  9. Alan

    Alan Guest

    "Tom Widmer" <> wrote in message news:41c6edc4$0$374$...
    > Alan wrote:
    > > I've put a virtual function in but it didn't fail until I introduced

    > a static
    > > variable into the class for instance counting. I've cut and cut the
    > > original program.. The code below (I'm using VC++6 too) succeeds
    > > or fails, per user choice. What puzzles me is why one class fails and
    > > the other doesn't - as the differences appear small.

    >
    > That's the nature of undefined behaviour. Understanding why it has a
    > certain effect often requires intimite knowledge of the compiler and its
    > optimizations. The policy is to *never* write any code that has
    > undefined behaviour, since even if such code appears to work here and
    > now, as soon as you demo the system to an investor, it will almost
    > certainly crash.


    If you could give me an example of the try..catch sequence (where the
    'try' fails and the 'catch' catches it) in code that has no undefined
    behaviour - it would be most helpful.

    tia
    sincerely,
    -Alan
     
    Alan, Dec 20, 2004
    #9
  10. Alan wrote:
    > "Tom Widmer" <> wrote in message news:41c6edc4$0$374$...
    >
    >>Alan wrote:
    >> > I've put a virtual function in but it didn't fail until I introduced

    >>a static
    >>
    >>>variable into the class for instance counting. I've cut and cut the
    >>>original program.. The code below (I'm using VC++6 too) succeeds
    >>>or fails, per user choice. What puzzles me is why one class fails and
    >>>the other doesn't - as the differences appear small.

    >>
    >>That's the nature of undefined behaviour. Understanding why it has a
    >>certain effect often requires intimite knowledge of the compiler and its
    >>optimizations. The policy is to *never* write any code that has
    >>undefined behaviour, since even if such code appears to work here and
    >>now, as soon as you demo the system to an investor, it will almost
    >>certainly crash.

    >
    >
    > If you could give me an example of the try..catch sequence (where the
    > 'try' fails and the 'catch' catches it) in code that has no undefined
    > behaviour - it would be most helpful.


    Try-catch blocks are used with throw. If nothing throws, a try-catch is
    useless.

    int main()
    {
    try
    {
    throw 2;
    }
    catch (int i)
    {
    std::cout << i << " was catched.";
    }
    }

    But I fail to see the point of your question. Using invalid pointers
    don't throw exceptions, it breaks your program.


    Jonathan
     
    Jonathan Mcdougall, Dec 20, 2004
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Robert Bauck Hamar
    Replies:
    1
    Views:
    328
    flekso
    Jul 2, 2003
  2. Ron Natalie
    Replies:
    25
    Views:
    664
    flekso
    Jul 8, 2003
  3. B. Penn
    Replies:
    6
    Views:
    612
    Old Wolf
    Aug 9, 2004
  4. Chumley the Walrus
    Replies:
    2
    Views:
    270
    Tom Gosselin
    Aug 10, 2004
  5. daniel rich
    Replies:
    5
    Views:
    325
    daniel rich
    Nov 14, 2012
Loading...

Share This Page