Why are you still trying to access "s" after you called its destructor in line 4? You should not be attempting to access deleted data/pointers after the fact. Line 9 would be OK if line 8 were uncommented, but lines 4 & 5 are always wrong to do (if done in that order).

I must admit that I've learned something today... because I didn't even realize that you could call a class destruct-or directly.

Typically, the destructor gets called automatically when a local class object goes out of scope, or you create the class object with 'new' and call the destructor via 'delete'.

The only thing I see that even allows this code to run as far as it does is the fact that calling ~A1() doesn't destroy the s object, it simply executes the code that is in the ~A1() function. If the class had been inherited, I'm not even sure that calling the ~A1() destructor function directly would properly call the base class destructors.

So bottom line, I think calling ~A1() directly is the wrong thing to ever do because you're interfering the with life-cycle of the object. By calling ~A1, you're not destroying the object, but you are executing some of the code normally associated with destroying the object. So I would compare it to an attempted suicide gone wrong.

Don't quote me, but perhaps the application is writing straight back to that location in memory since you have told it that you would like to delete it (via line 15), and that memory is now free (for the operating system) to use. It's the same size as what you requested before. (Remember: A pointer just holds an address to some other location in memory. The fact that it points to a string is inconsequential; the data actually being held by the pointer itself is a memory address.) If you ran this code over many repetitions, then you might see different behavior.

I missed the fact that you are loading 'u' with "go Beta" and printing 's' and getting "go Beta".

That would mean that what kaufmed (combined with what I said) is why you are getting the 'wrong' text.

You created 's' and assigned it to point to a 'new' string. You then called the 's' destructor. But you didn't really destroy 's', all you did was run the member function '~A1()'. That member function released the memory that s.p was pointing to. But it didn't change the memory location s.p was pointing to.

Then you created 'u' where a new string was created and u.p now points to. But if you look at the code with a debugger, you should find that u.p happens to be the exact same memory address that s.p was left pointing to.

Since 's' was never actually destroyed, it is still a valid object and s.p points to the string that 'u' created. You don't get a memory exception because the local function has access to the memory that u.p points to, but you're just reading the memory address using s.p.

If you change the ~A1() destructor to the following, your program with blow chunks with a memory exception.

Most programs will irrecoverably crash if it encounters a memory access violation (and most systems don't allow access to memory location 'NULL'). Even if you put try/catch blocks around the code that causes a memory access violation, the program will crash instead of throwing a catch-able exception (at least that's been my experience with Visual Studio... a special compiler option has to be set so that access violations will throw catch-able exceptions.)

Unless you've modified the code from what you first posted, 'p' is never NULL.

As the A1 object ('s' or 'u') is created, the pointer p is just random data left in memory until the line 'p = new ...' is executed.

When you delete 'p' on line 15, the value of 'p' doesn't change. The 'delete' just frees the memory that 'p' pointed to. But unless you change the value of 'p', the 'delete' command just leaves 'p' pointing to freed memory.

Now if you modify the code so that after 'delete p' you assign 'p = NULL', THEN line 9 in Main.cpp will crash because it will attempt to access NULL as it attempts to access the memory that 'p' is pointing to.

i often saw code in the destructor where pointers deleted were set to NULL like in the sample code HooKooDooKu has shown.

i thought it was just for readability or to please some purifier software. but, same as with HooKooDooKu, I never have seen code before which calls the destructor as a function.

But why and how can this happen that the address is valid after I deleted p

a pointer value is an address in the memory. the address is still valid if you free the pointer by delete as told by HooKooDooKu. the heap manager could check if it is valid as it "knows" whether a pointer was allocated or not, but the compiler has not added such a check when you access a pointer read-only after freeing. you even could write to that memory beside a debugger would do a check before write (i know debuggers which would write funny addresses like 0xefefefef to deleted pointers, which then really is invalid). if you definitively want to see a crash you would need to delete the pointer again. in any case, if your application grows, such code would lead to severe memory corruption and unpredictable crashes.

At this point, the only question I have is why after calling 's.~A1()' followed immediately by 'printf(s.p)' did apparently nothing print rather than what ever was left in memory that s.p was left pointing at. I can only GUESS that perhaps the memory it was pointed at after the destructor for 'p' was called that memory was somehow left with either unprintable characters or the memory address contained '0' (NULL).

Otherwise, I would have expected that 'delete p' would have left the text of the initial string alone having simply freed up memory. If that were happening, then I would expect the output to be:
go Gamaone
go Beta
two

(Note this exact output is because 'go Gama' didn't end with '\n', while the strings for 'one', 'go Beta', and 'two' do.

Introduction
This article is the first in a series of articles about the C/C++ Visual Studio Express debugger. It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints. Lastly, Part 3 focuses on th…

Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …

The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…