calling delete on the shallow copy not blow up [duplicate] - c++

This question already has answers here:
C++ delete - It deletes my objects but I can still access the data?
(13 answers)
Closed 4 years ago.
In the below code, memory is allocated for an integer and later a shallow copy is being made and finally delete is being called on it. How does it still print 23 as the output and why doesn't the delete call on q, cause a run time exception.
#include <iostream>
using namespace std;
int main() {
int* p = new int(23);
int* q = p;
delete p;
cout << *p << endl;
delete q;
return 0;
}

Undefined behaviour means anything can happen.
It might crash.
It might crash your car.
It might crash your brain.
It might crash Sagittarius A* into your brain.
It might crash your brain into your car, then crash them both into Sagittarius A*.
It might appear to work.
But it's still undefined.
Don't expect results.

Related

delete[] operator in C++ not working as it should [duplicate]

This question already has answers here:
What happens to the pointer itself after delete? [duplicate]
(3 answers)
Why doesn't delete set the pointer to NULL?
(12 answers)
Closed 2 years ago.
Please have a look at this below code::
#include<iostream>
using namespace std;
int main()
{
int *ptr;
ptr = new int[100000];
cout<<"\n\n address = "<<ptr;
for(long int i=0;i<100000;i++)
*(ptr+i) = i+1;
delete []ptr;
cout<<"\n\n address = "<<ptr;
ptr = new int[5];
cout<<"\n\n address = "<<ptr;
return 0;
}
OUTPUT is:
address = 0xd42490
address = 0xd42490
address = 0xe919d0
Why,After delete []ptr; it is still pointing to its previous location(See the 2nd output).
delete[] is working just as it should. It ensures that destructors are called for the members of the array and marks the memory (internally) as available for re-use.
There's nothing in the C++ standard that says it has to zero the memory or return the memory to the OS or clear the variable holding the address you passed to it, etc.
Once you delete something, you know destructors have run and you also know that you are no longer allowed to look at (access) that memory. If you do anyway, there's no guarantee what you'll get (except UB).
A pointer is just like a cardboard sign saying "there's something over there". When you use delete on the pointer it destroys what's "over there", but it doesn't re-write the sign itself (the pointer), so the pointer still points to the same memory location it always did, but accessing that memory location is now forbidden.
delete [] has destroyed the array created dynamically at address ptr, but has not deleted the pointer itself.
A ptr = nullptr; command would perform that job, by indicating that ptr now points to nothing.

Seg Fault Depending on Order of Pointer Assignment [duplicate]

This question already has answers here:
Dereferencing pointers without pointing them at a variable
(4 answers)
Closed 6 years ago.
Consider the following code:
#include <iostream>
int main()
{
// ok by itself
int *ptr1;
int a = 3;
*ptr1 = a;
// ok by itself
int *ptr2 = new int(4);
delete ptr2;
}
This results in a seg fault, and I can't figure out why. If either of the blocks are commented, it's okay. If the second block is placed above the first block, it's also okay. What's going on here?
You cannot dereference ptr1 because it's uninitialized.
With that said, *ptr1 = a is incorrect, and you're getting undefined behavior, which means that this code may or may not work as one expects.

Deleting an array created by new [] with delete [] [duplicate]

This question already has answers here:
How serious is the new/delete operator mismatch error?
(4 answers)
Closed 6 years ago.
Consider the following piece of code:
#include <iostream>
#include <limits>
using namespace std;
struct my{
int a;
~my(){
cout << "d\n";
}
};
int main(){
my* a = new my[100];
// cout << (void*)a << " " << (void*)&(a[0]) << endl;
delete a; // I know I should use delete [],
// but just to find out what would happen if I do this.
}
The program is printing d and then gives a segmentation fault. The implementation of delete assumes that an area of size sizeof(type) has been allocated and that much memory has to be freed. Whereas delete [] first reads the number of elements which has been allocated. I found that most implementations store this number n in the beginning of the allocated memory. delete [] fetches n from the beginning and the goes on to free n * sizeof(type) bytes of allocated memory. I don't understand why the above program gives segfault. I tried printing the addresses a and &(a[0]) and they are exactly the same, so any possibility that delete was trying to clear the area where n was stored is simply not true. Can someone please tell what is going on?
Note: This does not happen when we allocate arrays of basic types like int, double etc.
The behaviour on using delete on a pointer acquired by new[] is undefined. (Some C++ runtime libraries are implemented in such a way that an array of plain old data types is deleted correctly when you write delete).
Really there is nothing else to say.
what was allocated with new must be freed by delete, what was by new[] must be freed by delete[].
don't mix new for allocating and another APIs to free like Windows GlobalFree().
to delete correctly a:
delete[] a;
if you call delete in a dynamic array will cause an undefined behaviour

How to use delete with a variable pointed to by two pointers in C++ [duplicate]

This question already has answers here:
C++ delete - It deletes my objects but I can still access the data?
(13 answers)
Closed 7 years ago.
As it says here: How to use delete with a variable pointed to by two pointers?
one can only delete once, then all pointers won't work, but the code below:
#include<iostream>
using namespace std;
int main(){
string * str1 = new string("abc");
string * str2 = str1;
cout<< *str2 <<endl;
delete str1;
str1 = NULL;
cout<< *str2<<endl;
}
the output is:
abc
abc
so, what's the matter?
Once you have deleted a pointer, accessing it is undefined behavior and may print old contents sometimes, may crash sometimes or may do something beyond thinking some other time.
To handle a case of deleting shared pointer, use std::shared_ptr or similar reference counting manager wrapper instead of naked pointers.
One of the outcomes of undefined behavior is that is might seem to work. And dereferencing a pointer to a destructed object (like you do with cout<< *str2<<endl;) is undefined behavior.

c++ delete pointer issue, can still access data [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I don't really understand why are those pointer accessible ... any help appreciated
#include <iostream>
class Wicked{
public:
Wicked() {};
virtual ~Wicked() {};
int a;
int b;
};
class Test
{
public:
Test() {};
virtual ~Test() {};
int c;
Wicked * TestFunc()
{
Wicked * z;
c = 9;
z = new Wicked;
z->a = 1;
z->b = 5;
return z;
};
};
int main()
{
Wicked *z;
Test *t = new Test();
z = t->TestFunc();
delete z;
delete t;
// why can I set 'z' when pointer is already destroyed?
z->a = 10;
// why does z->a print 10?
std::cout << z->a << std::endl;
// why does t->c exist and print correct value?
std::cout << t->c << std::endl;
//------------------------------------------------------
int * p = new int;
*p = 4;
// this prints '4' as expected
std::cout << *p << std::endl;
delete p;
// this prints memory address as expected
std::cout << *p << std::endl;
return 0;
}
Deleting a pointer doesn't zero out any memory because to do so would take CPU cycles and that's not what C++ is about. What you have there is a dangling pointer, and potentially a subtle error. Code like this can sometimes work for years only to crash at some point in the future when some minor change is made somewhere else in the program.
This is a good reason why you should NULL out pointers when you've deleted the memory they point to, that way you'll get an immediate error if you try to dereference the pointer. It's also sometimes a good idea to clear the memory pointed to using a function like memset(). This is particularly true if the memory pointed to contains something confidential (e.g. a plaintext password) which you don't want other, possibly user facing, parts of your program from having access to.
That's undefined behaviour. Anything can happen.You were lucky this time. Or perhaps unlucky since it would be preferable to get a runtime error! Next time round maybe you'll get a runtime error.
It's not really very useful to reason about why you see a particular manifestation of undefined behaviour. It's best to stick to the well-defined behaviour about which you can reason.
C++ won't stop you from writing to an arbitrary location in memory. When you allocate memory with new or malloc, C++ finds some unused space in memory, marks it as allocated (so that it doesn't accidentally get handed out again), and gives you its address.
Once you delete that memory however, C++ marks it as free and may hand it out to anyone that asks for it. You can still write to it and read from it, but at this point, someone else might be using it. When you write to that place in memory, you may be overwriting some value you have allocated elsewhere.
Here
// why can I set 'z' when pointer is already destroyed?
z->a = 10;
z still points at a memory location.
But it no longer blongs to you. You have passed it to delete and said take care of this pointer. What it does is no longer your concern. Its like when you sell your car; it still exists but its not yours so opening the door and looking in may be possible, but it may result in the police arresting you.
Same with deleted pointers the memory exists but does not belong to you.
If you look inside it may work, but it may also cause a segmentation fault as the library has flushed the page (you never know).
delete z; just deallocates the memory z was pointing to, it does not destroy the pointer itself.
So z becomes a wild pointer.
Because deleting a block of memory does not zero the value of all pointers that point to it. Deleting memory merely makes a note that the memory is available to be allocated for some other purpose. Until that happens, the memory may appear to be intact -- but you can't count on it, and on some compiler/runtime/architecture combinations, your program will behave differently -- it may even crash.