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.
Related
This question already has answers here:
Can I delete[] a pointer that points into an allocated array, but not to the start of it?
(7 answers)
Why can't I delete pointer alone from an array of objects?
(4 answers)
Closed 5 years ago.
Consider, below program which gives runtime error. Point of this question is to understand memory view and management.
#include<iostream>
using namespace std;
int main(void) {
char* arr = new char[10];
char* ptr = NULL;
for(int i = 0; i < 10; i++) {
arr[i] = 'a';
}
cout << arr;
ptr = &arr[5];
delete ptr;
cout << arr;
return 0;
}
new allocates a block of memory. You can free that memory using delete, but you must pass the same address that was returned by new. That's how it works. You can't pass arbitrary addresses to delete.
Another option is to use malloc() and free(). These are older function but then you can also use realloc() to resize the memory. Then, if you want to delete part of the array, you can resize it to be smaller. BUT... you must still copy any data as needed to correctly form the resized array. That is not automatic.
This question already has answers here:
Code outside functions
(3 answers)
Closed 7 years ago.
I have a problem when using 'delete' operator. It is identified as a syntax error by VS2013 with Nov 2013 CTP compiler, giving the message: "expected a declaration". Here is the code:
int a = 1;
int* p = &a;
int* snj = new int[10];
delete p;
delete[] snj;
C++ doesn't let you write arbitrary expressions in the top-level like Python or other languages. You need to place your code in a function, probably main in this case:
int main()
{
int a = 1;
int* p = &a;
int* snj = new int[10];
delete p;
delete[] snj;
}
Note that using delete on a pointer which wasn't allocated using new is undefined behaviour.
Things like this are very basic and should be covered by your introductory book. If you don't have an introductory book, you should get one.
p points to the address of a. a is a local variable decalred on the stack. You can only call delete on dynalically allocated heap memory (Any variable created using the new keyword).
a is deleted automatically when it goes out of scope.
You should not delete p since it is not pointing to a heap element, it points to a stack element.
This question already has answers here:
Should new/new[] match delete/delete[]?
(3 answers)
Closed 9 years ago.
I am looking at the following code segment. It compiles well, but returns an error when the delete statement is included. The error is that the pointer being freed was not allocated. What have I missed here? My searches of the stack overflow site have not turned up a question that exactly duplicates this question. The link that points to a "duplicate" does not look like a duplicate to me.
The code is...
long val2 = 72;
long *pval2 = NULL;
pval2 = new long;
pval2 = &val2;
std::cout << "pval2 = " << *pval2 << "\n"; //prints the correct value
delete pval2;
The compiler I am using for this is project the c++ compiler that is in the Xcode development tool.
Thank you
pval2 = new long;
This gives you some memory space to play with.
pval2 = &val2;
This then immediately throws that memory space away and makes the pointer point to the location of val2 (which is not freeable memory). If you meant to copy the value of val2 into the new memory address, then you need to dereference the pointer:
*pval2 = val2;
You can only give to delete a memory address returned by new. &val2 is an address on the stack and send it to delete is an error.
Last, once you overwrite pval2 with &val2, you lost the previous memory address allocated on the heap, so it is a memory leakā¦
pval2 = new long; allocates a long and stores the address of it in pval2.
pval2 = &val2; then overwrites that address with a different one, that being the location of val2. At this point you've lost the address of that allocated long.
Consequently, when you finally get down to delete pval2; it tries to deallocate something which you never allocated with new in the first place and thus causes problems.
You are trying to delete something on the stack
this line pval2 = &val2; is pointing to something on the stack.
after the allocation pval2 points to somewhere in the heap. then you override this point to somewhere in the stack. now you got someplace on the heap which you cannot access - that's your mistake
This question already has answers here:
Is it good practice to NULL a pointer after deleting it?
(18 answers)
C++ - Why set object to null after deleting? [duplicate]
(6 answers)
Closed 9 years ago.
int* ptr = new int();
delete ptr;
ptr = 0; // or null
My book is telling me that it is good practice to set a pointer to null or 0 after deleting what it points to. I'm not understanding why. Could someone give me a scenario in which this could cause a problem?
Just so that you know the pointer does not point to anything anymore, and will fail if conditions and other boolean checks:
delete ptr;
ptr = NULL;
if(ptr)
*ptr = 2;
This code will run perfectly fine, although it would cause memory corruption if the pointer was not set to NULL.
That way, if you accidentally use ptr again later in your program, it causes a crash immediately rather than causing a hard-to-find bug later in the program.
What if you are referencing that pointer elsewhere in your code?
A lot of developers use simple checks to make sure they can still access that pointer or not.
int * blah = new int();
void changeBlah( void )
{
if( blah )
{
*blah = 1337;
}
}
Later if you call delete on the pointer you might still call the function that changes the value stored in the pointer.
delete blah;
changeBlah();
This function would run and become undefined as you would write over memory you don't own.
delete blah;
blah = 0;
changeBlah();
Now the code would run without any problems at all.
Because it is always safe to delete a null pointer. This is to avoid double delete errors. Developers also use it to check whether or not a pointer's already been deleted.
If you always set it to 0 after deleting it, you can use that to check whether the pointer is valid before you dereference it. So wherever you use it you can check like follows:
if(myPointer)
value = *myPointer;
If you did not set to 0 when deleting, you could never use this kind of construction.
Context: I'm trying to wrap my head around pointers, we just saw them a couple of weeks ago in school and while practicing today I ran into a silly? issue, it can be super straightforward to you but I have little to none programming experience.
I've seen quite a few questions over in SO about deleting pointers but they all seem to be related to deleting a class and not a 'simple' pointer (or whatever the proper term might be), here's the code I'm trying to run:
#include <iostream>;
using namespace std;
int main() {
int myVar,
*myPointer;
myVar = 8;
myPointer = &myVar;
cout << "delete-ing pointers " << endl;
cout << "Memory address: " << myPointer << endl;
// Seems I can't *just* delete it, as it triggers an error
delete myPointer;
cout << "myPointer: " << myPointer << endl;
// Error: a.out(14399) malloc: *** error for object 0x7fff61e537f4:
// pointer being freed was not allocated
// *** set a breakpoint in malloc_error_break to debug
// Abort trap: 6
// Using the new keyword befor deleting it works, but
// does it really frees up the space?
myPointer = new int;
delete myPointer;
cout << "myPointer: " << myPointer << endl;
// myPointer continues to store a memory address.
// Using NULL before deleting it, seems to work.
myPointer = NULL;
delete myPointer;
cout << "myPointer: " << myPointer << endl;
// myPointer returns 0.
}
So my questions are:
Why won't the first case work? Seems the most straightforward use to use and delete a pointer? The error says the memory wasn't allocated but 'cout' returned an address.
On the second example the error is not being triggered but doing a cout of the value of myPointer still returns a memory address?
Does #3 really work? Seems to work to me, the pointer is no longer storing an address, is this the proper way to delete a pointer?
Sorry for the long question, wanted to make this as clear as possible, also to reiterate, I have little programming experience, so if someone could answer this using layman's terms, it would be greatly appreciated!
1 & 2
myVar = 8; //not dynamically allocated. Can't call delete on it.
myPointer = new int; //dynamically allocated, can call delete on it.
The first variable was allocated on the stack. You can call delete only on memory you allocated dynamically (on the heap) using the new operator.
3.
myPointer = NULL;
delete myPointer;
The above did nothing at all. You didn't free anything, as the pointer pointed at NULL.
The following shouldn't be done:
myPointer = new int;
myPointer = NULL; //leaked memory, no pointer to above int
delete myPointer; //no point at all
You pointed it at NULL, leaving behind leaked memory (the new int you allocated).
You should free the memory you were pointing at. There is no way to access that allocated new int anymore, hence memory leak.
The correct way:
myPointer = new int;
delete myPointer; //freed memory
myPointer = NULL; //pointed dangling ptr to NULL
The better way:
If you're using C++, do not use raw pointers. Use smart pointers instead which can handle these things for you with little overhead. C++11 comes with several.
I believe you're not fully understanding how pointers work.
When you have a pointer pointing to some memory there are three different things you must understand:
- there is "what is pointed" by the pointer (the memory)
- this memory address
- not all pointers need to have their memory deleted: you only need to delete memory that was dynamically allocated (used new operator).
Imagine:
int *ptr = new int;
// ptr has the address of the memory.
// at this point, the actual memory doesn't have anything.
*ptr = 8;
// you're assigning the integer 8 into that memory.
delete ptr;
// you are only deleting the memory.
// at this point the pointer still has the same memory address (as you could
// notice from your 2nd test) but what inside that memory is gone!
When you did
ptr = NULL;
// you didn't delete the memory
// you're only saying that this pointer is now pointing to "nowhere".
// the memory that was pointed by this pointer is now lost.
C++ allows that you try to delete a pointer that points to null but it doesn't actually do anything, just doesn't give any error.
Pointers are similar to normal variables in that you don't need to delete them. They are removed from memory at the end of a functions execution and/or the end of the program.
You can however use pointers to allocate a 'block' of memory, for example like this:
int *some_integers = new int[20000]
This will allocate memory space for 20000 integers. Useful, because the Stack has a limited size and you might want to mess about with a big load of 'ints' without a stack overflow error.
Whenever you call new, you should then 'delete' at the end of your program, because otherwise you will get a memory leak, and some allocated memory space will never be returned for other programs to use. To do this:
delete [] some_integers;
Hope that helps.
There is a rule in C++, for every new there is a delete.
Why won't the first case work? Seems the most straightforward use to use and delete a pointer? The error says the memory wasn't allocated but 'cout' returned an address.
new is never called. So the address that cout prints is the address of the memory location of myVar, or the value assigned to myPointer in this case. By writing:
myPointer = &myVar;
you say:
myPointer = The address of where the data in myVar is stored
On the second example the error is not being triggered but doing a cout of the value of myPointer still returns a memory address?
It returns an address that points to a memory location that has been deleted. Because first you create the pointer and assign its value to myPointer, second you delete it, third you print it. So unless you assign another value to myPointer, the deleted address will remain.
Does #3 really work? Seems to work to me, the pointer is no longer storing an address, is this the proper way to delete a pointer?
NULL equals 0, you delete 0, so you delete nothing. And it's logic that it prints 0 because you did:
myPointer = NULL;
which equals:
myPointer = 0;
You are trying to delete a variable allocated on the stack. You can not do this
Deleting a pointer does not destruct a pointer actually, just the memory occupied is given back to the OS. You can access it untill the memory is used for another variable, or otherwise manipulated. So it is good practice to set a pointer to NULL (0) after deleting.
Deleting a NULL pointer does not delete anything.
int value, *ptr;
value = 8;
ptr = &value;
// ptr points to value, which lives on a stack frame.
// you are not responsible for managing its lifetime.
ptr = new int;
delete ptr;
// yes this is the normal way to manage the lifetime of
// dynamically allocated memory, you new'ed it, you delete it.
ptr = nullptr;
delete ptr;
// this is illogical, essentially you are saying delete nothing.