Say I have a pointer char* ptr
allocated memory and another pointer char* arr = ptr
What happens to arr
after ptr
memory is deallocated.
Let the function be:
char* foo()
{
char* ptr = new char [100];
char* arr = ptr;
delete [] ptr;
return arr;
}
Can I use this returned value?
Will it cause any compile-time/Run-time error? Or any thing else.
Or what would happen if the function was
char* foo()
{
char* ptr = new char [100];
char* arr = ptr;
delete [] arr;
return ptr;
}
I guess there would be no change from previous output but would there be any change??
What would happen If I have a class
class Pointer
{
public:
char* ptr;
Pointer()
{
ptr= new char [100];
}
~Pointer()
{
delete [] ptr;
}
};
and function
Pointer foo()
{
Pointer ptr;
ptr.ptr[0]='l';
return ptr;
}
Wont destructor be called at the end of the function and create a dangling pointer Pointer::ptr
??
Can I use this returned value??
You can "use" it, but you can't dereference it. You could, for example, print the pointer value out (but not the pointed-to data!):
std::cout << (intptr_t)foo() << std::endl; // OK
std::cout << foo(); // WRONG: this dereferences the pointer!
So while the value can be "used", it's not really useful as a pointer to char
anymore.
Or what would happen if the function was [...]
Both functions have the same meaning. On any decent compiler, you should expect both to yield identical machine code when compiled.
What happens to
arr
afterptr
memory is deallocated?
Nothing happens to it: its value remains unchanged. But because the pointed-to object has been deallocated, it is now a dangling pointer. So you can't use it for anything: if you do, you'll get undefined behavior. Undefined behavior means that anything can happen. This includes: nothing happening (things "appear" to "work OK"), or getting your hard drive formatted.
The situation is the same is if you built a house on a lot. You give your friend Arr
the GPS coordinates. But in the meantime you decided to move out. Yet your friend Arr
still has the old coordinates. Now Arr
decides to use them. There are several possible outcomes - and you have no control over which one happens. I'll list just a few:
You moved out an hour ago. Everything is still the same. Arr stopped by, took a picture of your old home, and left.
This corresponds to a case where due to a coincidence, the pointed-to memory still contains usable contents. You still have a bug, but coincidence hides it.
You moved out, but the next day the city decided to raze the lot and build a big condo building on it and adjacent lots. Your friend comes in expecting a small house, sees a big condo high-rise and ends up completely stumped.
This corresponds to a case where the memory gets reused followed by the dangling pointer dereference. Whether this leads to CPU raising an exception or not depends on what kind of an object lived there before.
You moved out, but there was an earthquake and there's now a lake there. Your friend falls in and drowns.
This corresponds to a case where a now-redundant chunk of virtual memory that used to be a part of the free store has been unmapped. You get a page fault.
The memory manager runtime can deallocate the page that used to back the address space pointed to by your pointer. Recall that often a C++ program runs on top of a virtual memory machine. The address space seen by the program is the virtual address space. When there's no physical memory page backing a given virtual address space page, and no file or other backing for that page, any accesses to it will cause a page fault that propagates to userland and terminates the process if unhandled (as it is by default).