This question already has answers here:
Is it safe to delete a NULL pointer?
(8 answers)
Closed 9 years ago.
I am trying to understand memory part in C++. I am trying to release memory after I generate the output by using the code below.
Question:
Is it necessary to release memory by using if-statement?
Code:
int main(){
char *pc;
int *pi;
pc = new char('a');
pi = new int(8);
cout << *pc << endl;
cout << *pi << endl;
//What's the purpose for doing if(pc) and if (pi) below?
if(pc){
delete pc;
}
if(pi){
delete pi;
}
return 0;
}
Could I be able to do in this way?
int main(){
char *pc;
int *pi;
pc = new char('a');
pi = new int(8);
cout << *pc << endl;
cout << *pi << endl;
delete pc;
delete pi;
return 0;
}
Is it necessary to use IF statement when releasing memory?
No, it is not (as long as you haven't overridden the global operator delete). This is perfectly fine and will do nothing:
int* p = nullptr;
delete p;
Per paragraph 3.7.4/2 of the C++11 Standard:
[...] The value of the
first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation
function is one supplied in the standard library, the call has no effect. [...]
As suggested by chris in the comments, however, consider using smart pointers rather than performing manual memory management through raw pointers, new, and delete (or their array counterpart).
In your particular code, the null checks are not needed.
In general, it's implementation specific whether delete (T*)0; will call the deallocation function for type T. If your implementation does pass null pointers to the deallocation function, and either your type has overridden the deallocation function by providing member operator delete, or you're provided a replacement global ::operator delete, and that custom deallocation function doesn't handle null pointer values well, you could have trouble.
The Standard does NOT require that a custom operator delete do nothing when passed a null pointer. It shouldn't fail, but it might write nasty log messages or tell your boss that someone isn't following the coding standard, for example.
No it's not but it's considered a good practice to do so. In real life scenario your code changes frequently due to business requirements, bugs, etc so it's always best to use this kind of defensive programming strategy.
The last thing you want is having a hard-to-detect error due to freeing already freed pointer because your colleague changed the upper portion of the code
Related
This question already has answers here:
C++ Is it possible to determine whether a pointer points to a valid object?
(6 answers)
Closed 4 years ago.
I have written following array pointer program in C++. I have deleted the pointer, but i am not able to confirm whether the pointer is deleted or not.
Thanks in advance!
#include<iostream>
using namespace std;
int main()
{
int *p;
p=new int[10];
int i=0;
if(!p)
{
cout<<"\ndynamic memory allocation failed"<<endl;
}
cout<<&p;
for(i=0;i<10;i++)
{
p[i]=i+1;
}
for(i=0;i<10;i++)
cout<<"\nvalue of pointer p="<<p[i];
delete[] p;
if(!p)
cout<<"\n\nmemory cannot be free";
}
How do i check whether the pointer is deleted or not in C++
There is no way to check whether a pointer is deleted or not in C++.
There is also no need to check whether a pointer was deleted. If you get a pointer from a new-expression, and you haven't yet deleted the pointer earlier, then it is safe to assume that delete will release that memory.
Its not about trusting the compiler. I just want to confirm whether it is deleted or not. If its deleted its good, but if it is not deleted then ...
Since it is not possible to test whether a pointer has been deleted or not, the trick is to structure the program such that there is never doubt about the state of the pointer.
The typical solution is to store the pointer as a private member variable of a class described as a "smart pointer", and to never let the post condition of any function of that class to leave the pointer in a deleted state. This establishes a class invariant that guarantees the validity of the pointer throughout the entire lifetime of the object and therefore there is never need to find out when the pointer can be deleted.
The standard library provides smart pointer classes for you, so there's hardly ever need to write delete or delete[] yourself.
In the case of dynamic arrays that you use as an example, you don't need to use any pointers. You can use std::vector instead:
{
std::vector<int> p(10);
}
// memory was freed; no need to test
If you want to be sure that your deleted pointer doesn't contain unsafe values you can make sure that you set it to nullptr after.
delete[] p;
p = nullptr;
If you then want to see if it's deleted, simply check with:
if (p != nullptr)
{
}
Hope this helps!
I'm sure this is answered somewhere, but I'm lacking the vocabulary to formulate a search.
#include <iostream>
class Thing
{
public:
int value;
Thing();
virtual ~Thing() { std::cout << "Destroyed a thing with value " << value << std::endl; }
};
Thing::Thing(int newval)
{
value = newval;
}
int main()
{
Thing *myThing1 = new Thing(5);
std::cout << "Value 1: " << myThing1->value << std::endl;
Thing myThing2 = Thing(6);
std::cout << "Value 2: " << myThing2.value << std::endl;
return 0;
}
Output indicates myThing2 was destroyed, my myThing1 was not.
So... do I need to deconstruct it manually somehow? Is this a memory leak? Should I avoid using the * in this situation, and if so, when would it be appropriate?
The golden rule is, wherever you use a new you must use a delete. You are creating dynamic memory for myThing1, but you never release it, hence the destructor for myThing1 is never called.
The difference between this and myThing2 is that myThing2 is a scoped object. The operation:
Thing myThing2 = Thing(6);
is not similar at all to:
Thing *myThing1 = new Thing(5);
Read more about dynamic allocation here. But as some final advice, you should be using the new keyword sparingly, read more about that here:
Why should C++ programmers minimize use of 'new'?
myThing1 is a Thing* not a Thing. When a pointer goes out of scope nothing happens except that you leak the memory it was holding as there is no way to get it back. In order for the destructor to be called you need to delete myThing1; before it goes out of scope. delete frees the memory that was allocated and calls the destructor for class types.
The rule of thumb is for every new/new[] there should be a corresponding delete/delete[]
You need to explicitly delete myThing1 or use shared_ptr / unique_ptr.
delete myThing1;
The problem is not related to using pointer Thing *. A pointer can point to an object with automatic storage duration.
The problem is that in this statement
Thing *myThing1 = new Thing(5);
there is created an object new Thing(5) using the new operator. This object can be deleted by using the delete operator.
delete myThing1;
Otherwise it will preserve the memory until the program will not finish.
Thing myThing2 = Thing(6);
This line creates a Thing in main's stack with automatic storage duration. When main() ends it will get cleaned up.
Thing *myThing1 = new Thing(5);
This, on the other hand, creates a pointer to a Thing. The pointer resides on the stack, but the actual object is in the heap. When the pointer goes out of scope nothing happens to the pointed-to thing, the only thing reclaimed is the couple of bytes used by the pointer itself.
In order to fix this you have two options, one good, one less good.
Less good:
Put a delete myThing1; towards the end of your function. This will free to allocated object. As noted in other answers, every allocation of memory must have a matching deallocation, else you will leak memory.
However, in modern C++, unless you have good reason not to, you should really be using shared_ptr / unique_ptr to manage your memory. If you had instead declared myThing1 thusly:
shared_ptr<Thing> myThing1(new Thing(5));
Then the code you have now would work the way you expect. Smart pointers are powerful and useful in that they greatly reduce the amount of work you have to do to manage memory (although they do have some gotchas, circular references take extra work, for example).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
how to safely delete multiple pointers
As the code below:
#include <iostream>
using namespace std;
int main(int argc, _TCHAR* argv[])
{
int *p, *q;
q = new int;
p = q;
delete q;
q = NULL;
cout << p << " " <<q << endl;
return 0;
}
p point to q. When I delete q and q = NULL, p still points to the old address.
Does anyone have any method to make p point to q NULL automatically?
Because if in a program there are lots of pointers that point to the same address and we can't make them point to NULL it would bring problems.
There is a type of smart pointer which can do the job. There may be issues with thread safety with this code,(in fact I guarantee there will be).
template <class T>
class DoublyLinkedSmartPointer
{
public:
DoublyLinkedSmartPointer(const DoublyLinkedSmartPointer &other);
DoublyLinkedSmartPointer& operator=(const DoublyLinkedSmartPointer& other);
virtual ~DoubleLinkedSmartPointer();
T * operator*();
const T* operator*() const;
void freeAll();
private:
DoublyLinkedSmartPointer *next, *previous;
T * data;
}
The basic idea is, whenever a copy is made of the smart pointer, you add the copy into the
list using the smart pointer used to initialise it. And when you remove the pointer, you
free it from the list.
Now, the tricky bit, since every pointer knows every other pointer, you can step through the list from any point, and set data to NULL in every node.
Okay, so that's how you could do it. But more importantly, don't do it. You are almost certainly going to create code which is hard to maintain, and near impossible to debug. The best memory management strategies are the simplest.
The general advise for C++ programs is to avoid elementary pointers, precisely to avoid the issues you're having. Instead, use the language's (or more precisely its standard library's) methods to deal with pointers:
1 use containers, such as std::vector, instead of pointers to (chunks of) memory allocated on the heap
2 use std::unique_ptr and std::shared_ptr (and std::weak_ptr) to manage objects allocated on the heap. This only works properly in C++11 with its move semantics, see the standard header .
advantages: automatic de-allocation without leaving dangling pointers; exception safety (throwing an exception and stack-rewinding does not leak memory).
I have a function foo like
myType** foo(){
myType **array = malloc( .... );
//Do some stuff
return array;
}
Here I have malloced , but did not free it as I am returning it . Will this cause a memory leak ? Should I explicitly free it in the calling function after I use it ?
It's a memory leak only if you don't free the memory (regardless where).
In this case, you should free it after the function is called and you're done with the pointer.
But this is the C way of doing it. In C++ you'd return a smart pointer, and use new instead of malloc.
With this type of function, the caller is the "owner" of the resources pointed at by the pointer. So the caller has to either free the resources, or pass them on to someone else who will.
In C++ one would favour returning a type that manages its own resources, for example an std::vector, or a smart pointer, that both takes care of resource de-allocation and makes the ownership clear.
See this example,and don't worry, read all about copy elision, particularly named return value optimization (NRVO).
std::vector<std::vector<SomeType>> foo()
{
std::vector<std::vector<SomeType>> tmp = ....;
// do some stuff
return tmp;
}
Memory leaks are caused by not freeing memory. As long as the memory will get freed at some point, then it isn't leaked. But if the pointer ever gets "lost" or if some sort of dependency loop causes a situation where the memory stays around even after it is no longer useful, then at that point you've created a leak.
Usually in this type of situation, you create a pattern like this:
void* mything_init() {
void *obj = malloc(LEN);
// do some initialization
return obj;
}
void mything_uninit(void* thing) {
// any teardown
free(thing);
}
For every mything that you _init, you must eventually call _uninit on that object. That is your responsibility as the user of that library. While as the writer of that library, you make sure that anything you allocate in the _init gets properly freed in _uninit.
This is a C pattern rather than a C++ pattern as malloc() is a C idiom. C++ uses new and delete, and this sort of work us usually done in a constructor/destructor pair.
I had issues about this problem for long time. I suggest you to read this wiki page:
Smart Pointers
In your case you can use unique_ptr. So you would be able to transfer the ownership of the pointer to the caller function.
unique_ptr<int> callee1()
{
std::unique_ptr<int> p1(new int(5));
return p1;
}
int main()
{
std::unique_ptr<int> result = callee1() ;
(*result)++; // Increase the value stored in the pointer
std::cout << "New Value: " << (*result) << std::endl;
result.reset() ;
}
Hope this code sniper helps you.
I often see legacy code checking for NULL before deleting a pointer, similar to,
if (NULL != pSomeObject)
{
delete pSomeObject;
pSomeObject = NULL;
}
Is there any reason to checking for a NULL pointer before deleting it? What is the reason for setting the pointer to NULL afterwards?
It's perfectly "safe" to delete a null pointer; it effectively amounts to a no-op.
The reason you might want to check for null before you delete is that trying to delete a null pointer could indicate a bug in your program.
Edit
NOTE: if you overload the delete operator, it may no longer be "safe" to delete NULL
The C++ standard guarantees that it is legal to use a null pointer in a delete-expression (§8.5.2.5/2). However, it is unspecified whether this will call a deallocation function (operator delete or operator delete[]; §8.5.2.5/7, note).
If a default deallocation function (i.e. provided by the standard library) is called with a null pointer, then the call has no effect (§6.6.4.4.2/3).
But it is unspecified what happens if the deallocation function is not provided by the standard library — i.e. what happens when we overload operator delete (or operator delete[]).
A competent programmer would handle null pointers accordingly inside the deallocation function, rather than before the call, as shown in OP’s code.Likewise, setting the pointer to nullptr/NULL after the deletion only serves very limited purpose. Some people like to do this in the spirit of defensive programming: it will make program behaviour slightly more predictable in the case of a bug: accessing the pointer after deletion will result in a null pointer access rather than a access to a random memory location. Although both operations are undefined behaviour, the behaviour of a null pointer access is a lot more predictable in practice (it most often results in a direct crash rather than memory corruption). Since memory corruptions are especially hard to debug, resetting deleted pointers aids debugging.
— Of course this is treating the symptom rather than the cause (i.e. the bug). You should treat resetting pointers as code smell. Clean, modern C++ code will make memory ownership clear and statically checked (by using smart pointers or equivalent mechanisms), and thus provably avoid this situation.
Bonus: An explanation of overloaded operator delete:
operator delete is (despite its name) a function that may be overloaded like any other function. This function gets called internally for every call of operator delete with matching arguments. The same is true for operator new.
Overloading operator new (and then also operator delete) makes sense in some situations when you want to control precisely how memory is allocated. Doing this isn't even very hard, but a few precautions must be made to ensure correct behaviour. Scott Meyers describes this in great detail Effective C++.
For now, let's just say that we want to overload the global version of operator new for debugging. Before we do this, one short notice about what happens in the following code:
klass* pobj = new klass;
// … use pobj.
delete pobj;
What actually happens here? Well the above can be roughly translated to the following code:
// 1st step: allocate memory
klass* pobj = static_cast<klass*>(operator new(sizeof(klass)));
// 2nd step: construct object in that memory, using placement new:
new (pobj) klass();
// … use pobj.
// 3rd step: call destructor on pobj:
pobj->~klass();
// 4th step: free memory
operator delete(pobj);
Notice step 2 where we call new with a slightly odd syntax. This is a call to so-called placement new which takes an address and constructs an object at that address. This operator can be overloaded as well. In this case, it just serves to call the constructor of the class klass.
Now, without further ado here's the code for an overloaded version of the operators:
void* operator new(size_t size) {
// See Effective C++, Item 8 for an explanation.
if (size == 0)
size = 1;
cerr << "Allocating " << size << " bytes of memory:";
while (true) {
void* ret = custom_malloc(size);
if (ret != 0) {
cerr << " # " << ret << endl;
return ret;
}
// Retrieve and call new handler, if available.
new_handler handler = set_new_handler(0);
set_new_handler(handler);
if (handler == 0)
throw bad_alloc();
else
(*handler)();
}
}
void operator delete(void* p) {
cerr << "Freeing pointer # " << p << "." << endl;
custom_free(p);
}
This code just uses a custom implementation of malloc/free internally, as do most implementations. It also creates a debugging output. Consider the following code:
int main() {
int* pi = new int(42);
cout << *pi << endl;
delete pi;
}
It yielded the following output:
Allocating 4 bytes of memory: # 0x100160
42
Freeing pointer # 0x100160.
Now, this code does something fundamentally different than the standard implementation of operator delete: It didn't test for null pointers! The compiler doesn't check this so the above code compiles but it may give nasty errors at run-time when you try to delete null pointers.
However, as I said before, this behaviour is actually unexpected and a library writer should take care to check for null pointers in the operator delete. This version is much improved:
void operator delete(void* p) {
if (p == 0) return;
cerr << "Freeing pointer # " << p << "." << endl;
free(p);
}
In conclusion, although a sloppy implementation of operator delete may require explicit null checks in the client code, this is non-standard behaviour and should only be tolerated in legacy support (if at all).
Deleting null is a no-op. There's no reason to check for null before calling delete.
You might want to check for null for other reasons if the pointer being null carries some additional information you care about.
Delete checks for NULL internally. Your test is redundent
According to C++03 5.3.5/2, it's safe to delete a null pointer.
This following is quoted from the standard:
In either alternative, if the value of the operand of delete is the
null pointer the operation has no effect.
If pSomeObject is NULL, delete won't do anything. So no, you don't have to check for NULL.
We consider it good practice to assign NULL to the pointer after deleting it if it's at all possible that some knucklehead can attempt to use the pointer. Using a NULL pointer is slightly better than using a pointer to who knows what (the NULL pointer will cause a crash, the pointer to deleted memory may not)
There is no reason to check for NULL prior to delete.
Assigning NULL after delete might be necessary if somewhere in the code checks are made whether some object is already allocated by performing a NULL check. An example would be some sort of cached data that is allocated on demand. Whenever you clear out the cache-object you assign NULL to the pointer so the code that allocates the object knows that it needs to perform an allocation.
I believe the previous developer coded it "redundantly" to save some milliseconds:
It's a good thing to have the pointer be set to NULL upon being deleted, so you could use a line like the following right after deleting the object:
if(pSomeObject1!=NULL) pSomeObject1=NULL;
But then delete is doing that exact comparison anyway (doing nothing if it's NULL). Why do this twice? You can always assign pSomeObject to NULL after calling delete, regardless of its current value - but this would be slightly redundant if it had that value already.
So my bet is the author of those lines tried to ensure pSomeObject1 would always be NULL after being deleted, without incurring the cost of a potentially unnecessary test and assignation.
It depends on what you are doing. Some older implementations of free, for example, will not be happy if they are passed a NULL pointer. Some libraries still have this problem. For example, XFree in the Xlib library says:
DESCRIPTION
The XFree function is a
general-purpose Xlib routine that
frees the specified data. You must
use it to free any objects that were
allocated by Xlib, unless an alternate
function is explicitly specified for
the object. A NULL pointer cannot be
passed to this function.
So consider freeing NULL pointers as a bug and you'll be safe.
As for my observations, deleting a null pointer using delete is safe in unix based machines ike PARISC and itanium. But is quite unsafe for Linux systems as the process would crash then.