Is it considered good style to dereference `new` pointer? - c++

To avoid keep having to use -> and instead work directly with the object, is it acceptable practice to do:
obj x = *(new obj(...));
...
delete &obj;

This is not just poor practice, but:
Leaking memory (most likely, unless you are using some pattern that is not visible from the code you provided), since obj will store a copy of the original object created by the new expression, and the pointer to that object returned by new is lost;
Most importantly, undefined behavior, since you are passing to delete a pointer to an object that was not allocated with new. Per paragraph 5.3.5/2 of the C++11 Standard:
[...] In the first alternative (delete object), the value of the operand of delete may be a null pointer
value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8)
representing a base class of such an object (Clause 10). If not, the behavior is undefined.

No, and in fact this leads to a leak. x is copy initialized, so the original object pointed to by new obj is lost.
Just use
obj x(...);
No need for dynamic allocation. Or
obj x = obj(...);
if you must (doubt it).

Certainly not; that copies the dynamic object to an automatic variable, loses the only pointer to it, and then attempts to delete the automatic copy. You've got a memory leak and an invalid deletion.
Much better would be to use an automatic variable in the first place:
obj x(...);
...
// no need to delete anything
or, if it really must be dynamic for some reason (because it's too big for the stack, or you don't always want to destroy it here), then use a smart pointer, and a reference if you really don't like ->
std::unique_ptr<obj> p(new obj(...));
obj & x = *p;
...
// still no need to delete anything
Changing your x into a reference would be valid (as long as you're careful that exceptions, early function returns, etc. won't cause a leak), but would cause howls of confusion among anyone unfortunate enough to have to maintain it.

You cannot delete your object properly if you do it like that.
Implicitly you do the following.
class A
{
public:
int test (void) { return 1; }
};
int main (void)
{
A * p = new A;
A v(*p);
//...
delete &v; // &v != p and v is not constructed via new!
return 0;
}
If you want to work with an object-like-syntax you can bind a reference to the object.
class A
{
public:
int test (void) { return 1; }
};
int main (void)
{
A * p = new A;
A & r = *p;
int i = r.test();
delete p;
return 0;
}
If you delete your object through the same pointer, there will be no leak.

Related

Deleting an object by function in C++

I'm a bit curious about a pointer's behaviour in C++. So I have this little program to test out and unfortunately it run well.
#include <iostream>
class Test{
public:
Test(){
std::cout<<"Test Created!\n";
}
~Test(){
std::cout<<"Test Destroyed!\n";
}
};
void destroyer(Test* T){
Test* temp = T;
delete temp;
}
int main(){
Test* ptr = new Test();
destroyer(ptr);
}
And it gives in return
Test Created!
Test Destroyed!
And I draw the conclusion that when we delete a pointer, actually it just deletes the object that the pointer refers to, not the variable itself (variable pointer will automatically deleted at the end of program, same as other primitive data type). Is my thought about this true?
Yes, the delete operator only calls the destructor and frees the memory occupied by the object that the pointer points to. The pointer itself is a local variable like any other and cannot be (and does not need to be) deleted.
It may be worth noting that calling delete ptr; does not change the value of ptr, so after deleting the pointer ptr would point to memory that has been deallocated. It would be undefined behaviour to access that memory after deleting it.
delete is an operator that looks at the object pointed to by the pointer object. The pointer variable is still a local value whose lifetime is tied to the scope it is declared in.
You have 3 pointer objects, with differing lifetimes. Only ptr in main lasts to the end of the program. T and temp only exist during destroyer.
Colloquially we say "delete the pointer" when we write
delete x;
However, this isnt quite accurate. What is deleted is the object pointed to by x.
And i have conclusion that when we delete pointer, actually it just delete the object that pointer refer to not the variable itself (variable pointer will automatically deleted at the end of program, same as other primitive data type). Is my thought about this true?
Yes.
In practice the inaccuracy mentioned above is just fine because after deleting the object the pointer value cannot be used without invoking either implementation defined or undefined behavior and that also affects other pointers to the same object:
int* x = new int(42);
int* y = x;
detele x;
std::cout << x << y; // implementation defined
std::cout << *x << *y; // undefined
x = new int(42); // OK
For details see here.

Memory leak while deleting vector of pointers [duplicate]

To avoid keep having to use -> and instead work directly with the object, is it acceptable practice to do:
obj x = *(new obj(...));
...
delete &obj;
This is not just poor practice, but:
Leaking memory (most likely, unless you are using some pattern that is not visible from the code you provided), since obj will store a copy of the original object created by the new expression, and the pointer to that object returned by new is lost;
Most importantly, undefined behavior, since you are passing to delete a pointer to an object that was not allocated with new. Per paragraph 5.3.5/2 of the C++11 Standard:
[...] In the first alternative (delete object), the value of the operand of delete may be a null pointer
value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8)
representing a base class of such an object (Clause 10). If not, the behavior is undefined.
No, and in fact this leads to a leak. x is copy initialized, so the original object pointed to by new obj is lost.
Just use
obj x(...);
No need for dynamic allocation. Or
obj x = obj(...);
if you must (doubt it).
Certainly not; that copies the dynamic object to an automatic variable, loses the only pointer to it, and then attempts to delete the automatic copy. You've got a memory leak and an invalid deletion.
Much better would be to use an automatic variable in the first place:
obj x(...);
...
// no need to delete anything
or, if it really must be dynamic for some reason (because it's too big for the stack, or you don't always want to destroy it here), then use a smart pointer, and a reference if you really don't like ->
std::unique_ptr<obj> p(new obj(...));
obj & x = *p;
...
// still no need to delete anything
Changing your x into a reference would be valid (as long as you're careful that exceptions, early function returns, etc. won't cause a leak), but would cause howls of confusion among anyone unfortunate enough to have to maintain it.
You cannot delete your object properly if you do it like that.
Implicitly you do the following.
class A
{
public:
int test (void) { return 1; }
};
int main (void)
{
A * p = new A;
A v(*p);
//...
delete &v; // &v != p and v is not constructed via new!
return 0;
}
If you want to work with an object-like-syntax you can bind a reference to the object.
class A
{
public:
int test (void) { return 1; }
};
int main (void)
{
A * p = new A;
A & r = *p;
int i = r.test();
delete p;
return 0;
}
If you delete your object through the same pointer, there will be no leak.

Check for non-deallocated pointer

Assume a pointer object is being allocated on one point and it is being returned to different nested functions. At one point, I want to de-allocate this pointer after checking whether it is valid or already de-allocated by someone.
Is there any guarantee that any of these will work?
if(ptr != NULL)
delete ptr;
OR
if(ptr)
delete ptr;
This code does not work. It always gives Segmentation Fault
#include <iostream>
class A
{
public:
int x;
A(int a){ x=a;}
~A()
{
if(this || this != NULL)
delete this;
}
};
int main()
{
A *a = new A(3);
delete a;
a=NULL;
}
EDIT
Whenever we talk about pointers, people start asking, why not use Smart Pointers.
Just because smart pointers are there, everyone cannot use it.
We may be working on systems which use old style pointers. We cannot convert all of them to smart pointers, one fine day.
if(ptr != NULL) delete ptr;
OR
if(ptr) delete ptr;
The two are actually equivalent, and also the same as delete ptr;, because calling delete on a NULL pointer is guaranteed to work (as in, it does nothing).
And they are not guaranteed to work if ptr is a dangling pointer.
Meaning:
int* x = new int;
int* ptr = x;
//ptr and x point to the same location
delete x;
//x is deleted, but ptr still points to the same location
x = NULL;
//even if x is set to NULL, ptr is not changed
if (ptr) //this is true
delete ptr; //this invokes undefined behavior
In your specific code, you get the exception because you call delete this in the destructor, which in turn calls the destructor again. Since this is never NULL, you'll get a STACK OVERFLOW because the destructor will go uncontrollably recursive.
Do not call delete this in the destructor:
5.3.5, Delete: If the value of the operand of the delete-expression is not a null pointer value, the delete-expression will
invoke the destructor (if any) for the object or the elements of the array being deleted.
Therefore, you will have infinite recursion inside the destructor.
Then:
if (p)
delete p;
the check for p being not null (if (x) in C++ means if x != 0) is superfluous. delete does that check already.
This would be valid:
class Foo {
public:
Foo () : p(0) {}
~Foo() { delete p; }
private:
int *p;
// Handcrafting copy assignment for classes that store
// pointers is seriously non-trivial, so forbid copying:
Foo (Foo const&) = delete;
Foo& operator= (Foo const &) = delete;
};
Do not assume any builtin type, like int, float or pointer to something, to be initialized automatically, therefore, do not assume them to be 0 when not explicitly initializing them (only global variables will be zero-initialized):
8.5 Initializers: If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an
object with automatic or dynamic storage duration has indeterminate value. [ Note: Objects with static or thread storage duration are zero-initialized
So: Always initialize builtin types!
My question is how should I avoid double delete of a pointer and prevent crash.
Destructors are ought to be entered and left exactly once. Not zero times, not two times, once.
And if you have multiple places that can reach the pointer, but are unsure about when you are allowed to delete, i.e. if you find yourself bookkeeping, use a more trivial algorithm, more trivial rules, or smart-pointers, like std::shared_ptr or std::unique_ptr:
class Foo {
public:
Foo (std::shared_ptr<int> tehInt) : tehInt_(tehInt) {}
private:
std::shared_ptr<int> tehInt_;
};
int main() {
std::shared_ptr<int> tehInt;
Foo foo (tehInt);
}
You cannot assume that the pointer will be set to NULL after someone has deleted it. This is certainly the case with embarcadero C++ Builder XE. It may get set to NULL afterwards but do not use the fact that it is not to allow your code to delete it again.
You ask: "At one point, I want to de-allocate this pointer after checking whether it is valid or already de-allocated by someone."
There is no portable way in C/C++ to check if a >naked pointer< is valid or not. That's it. End of story right there. You can't do it. Again: only if you use a naked, or C-style pointer. There are other kinds of pointers that don't have that issue, so why don't use them instead!
Now the question becomes: why the heck do you insist that you should use naked pointers? Don't use naked pointers, use std::shared_ptr and std::weak_ptr appropriately, and you won't even need to worry about deleting anything. It'll get deleted automatically when the last pointer goes out of scope. Below is an example.
The example code shows that there are two object instances allocated on the heap: an integer, and a Holder. As test() returns, the returned std::auto_ptr<Holder> is not used by the caller main(). Thus the pointer gets destructed, thus deleting the instance of the Holder class. As the instance is destructed, it destructs the pointer to the instance of the integer -- the second of the two pointers that point at that integer. Then myInt gets destructed as well, and thus the last pointer alive to the integer is destroyed, and the memory is freed. Automagically and without worries.
class Holder {
std::auto_ptr<int> data;
public:
Holder(const std::auto_ptr<int> & d) : data(d) {}
}
std::auto_ptr<Holder> test() {
std::auto_ptr<int> myInt = new int;
std::auto_ptr<Holder> myHolder = new Holder(myInt);
return myHolder;
}
int main(int, char**) {
test(); // notice we don't do any deallocations!
}
Simply don't use naked pointers in C++, there's no good reason for it. It only lets you shoot yourself in the foot. Multiple times. With abandon ;)
The rough guidelines for smart pointers go as follows:
std::auto_ptr -- use when the scope is the sole owner of an object, and the lifetime of the object ends when the scope dies. Thus, if auto_ptr is a class member, it must make sense that the pointed-to object gets deletes when the instance of the class gets destroyed. Same goes for using it as an automatic variable in a function. In all other cases, don't use it.
std::shared_ptr -- its use implies ownership, potentially shared among multiple pointers. The pointed-to object's lifetime ends when the last pointer to it gets destroyed. Makes managing lifetime of objects quite trivial, but beware of circular references. If Class1 owns an instance of Class2, and that very same instance of Class2 owns the former instance of Class1, then the pointers themselves won't ever delete the classes.
std::weak_ptr -- its use implies non-ownership. It cannot be used directly, but has to be converted back to a shared_ptr before use. A weak_ptr will not prevent an object from being destroyed, so it doesn't present circular reference issues. It is otherwise safe in that you can't use it if it's dangling. It will assert or present you with a null pointer, causing an immediate segfault. Using dangling pointers is way worse, because they often appear to work.
That's in fact the main benefit of weak_ptr: with a naked C-style pointer, you'll never know if someone has deleted the object or not. A weak_ptr knows when the last shared_ptr went out of scope, and it will prevent you from using the object. You can even ask it whether it's still valid: the expired() method returns true if the object was deleted.
You should never use delete this. For two reasons, the destructor is in the process of deleting the memory and is giving you the opportunity to tidy up (release OS resources, do a delete any pointers in the object that the object has created). Secondly, the object may be on the stack.

c++ must delete a references?

in the following code:
class x
{
private:
someRef& m_ref;
public:
x(someRef& someRef):m_ref(someRef)
{
}
do I need to do:
~x()
{
delete m_ref;
}
which by the way doesnt work without getting the pointer...
basically I'm asking: Do I need to call a destructor on a reference member?
No.
You only need to delete an object if you own it. If you were passed a reference, it means that someone else owns it, thus it's unnecessary and thankfully the language prevents it.
I don't think one actually strictly speaking ever deletes even pointers. What you delete are dynamically allocated objects (or arrays of objects) that the pointer is a handle for. If the object originates from a call to new and it is the responsibility of this class to clean up after this object, then you call delete.
It is technically possible that a reference might be referring to a dynamically allocated object:
int main()
{
//in principle a reference can also refer to a dynamically allocated object
x var(*new someRef);
}
//and if that is the intended usage:
x::~x()
{
delete &m_ref;
}
However, this would be incredibly bad style. By convention, the "owning" handle of a dynamically allocated object should not be a reference.
No. You can only delete pointers, not references, and even then you must only delete objects that you allocated using the new operator. And then you must be sure to delete them only once. Here is the case in which you would need to use delete in your destructor:
class x
{
private:
someObj* m_ptr;
public:
x():m_ptr(new someObj())
{
}
~x()
{
delete m_ptr;
}
But in general it's best to avoid even this and use smart pointers instead.
I want to clarify some misconceptions you seem to have that are beyond the intent of your question:
When a class's destructor is called all of it's members' destructors get called as well.
Calling delete is not the same as calling the destructor. delete explicitly calls the destructor and also calls operator delete at the objects location, it is a 2 part thing.
For a small bit of extra clarification I want to offer the following:
int *pi = new int;
//int& ir = pi; // can't do
// this a reference to the pointer but it is an error
// because or the type difference int& vs int* and
// static_cast won't help. reinterpret_cast would allow
// the assignment to take place but not help the 'delete ir'
int& ir = *pi; // this is OK - a reference to what the pointer points to.
// In other words, the the address of the int on the heap.
//delete ir; // can't do, it is a reference and you can't delete non-pointers.
delete &ir; // this works but it is still not "deleting a reference".
// The reference 'ir' is another name for the heap-based int.
// So, &ir is the address of that int, essentially a pointer.
// It is a pointer that is being used by delete, not a reference.

Why doesn't the C++ default destructor destroy my objects?

The C++ specification says the default destructor deletes all non-static members. Nevertheless, I can't manage to achieve that.
I have this:
class N {
public:
~N() {
std::cout << "Destroying object of type N";
}
};
class M {
public:
M() {
n = new N;
}
// ~M() { //this should happen by default
// delete n;
// }
private:
N* n;
};
Then this should print the given message, but it doesn't:
M* m = new M();
delete m; //this should invoke the default destructor
What makes you think the object n points to should be deleted by default? The default destructor destroys the pointer, not what it's pointing to.
Edit: I'll see if I can make this a little more clear.
If you had a local pointer, and it went out of scope, would you expect the object it points to to be destroyed?
{
Thing* t = new Thing;
// do some stuff here
// no "delete t;"
}
The t pointer is cleaned up, but the Thing it points to is not. This is a leak. Essentially the same thing is happening in your class.
Imagine something like this:
class M {
public:
M() { }
// ~M() { // If this happens by default
// delete n; // then this will delete an arbitrary pointer!
// }
private:
N* n;
};
You're on your own with pointers in C++. No one will automatically delete them for you.
The default destructor will indeed destroy all member objects. But the member object in this case is a pointer itself, not the thing it points to. This might have confused you.
However, if instead of a simple built-in pointer, you will use a smart pointer, the destruction of such a "pointer" (which is actually a class) might trigger the destruction of the object pointed to.
The default destructor is destroying the pointer. If you want to delete the N with M's default destructor, use a smart pointer. Change N * n; to auto_ptr<N> n; and n will be destroyed.
Edit: As pointed out in comments, auto_ptr<> is not the best smart pointer for all uses, but it looks like what's called for here. It specifically represents ownership: the N in an M is there for the duration of the M and no longer. Copying or assigning an auto_ptr<> represents a change in ownership, which is usually not what you want. If you wanted to pass a pointer from M, you should pass a N * gotten from n.get().
A more general solution would be boost::shared_ptr<>, which will be in the C++0x standard. That can be used pretty much wherever a raw pointer would be used. It's not the most efficient construct, and has problems with circular references, but it's generally a safe construct.
Another edit: To answer the question in another comment, the standard behavior of the default destructor is to destroy all data members and base classes. However, deleting a raw pointer simply removes the pointer, not what it points to. After all, the implementation can't know if that's the only pointer, or the important one, or anything like that. The idea behind smart pointers is that deleting a smart pointer will at least lead to the deletion of what it points to, which is usually the desired behavior.
Is there any reason why you use a pointer when the pointed-to object seems to belong the contained object? Just store the object by value:
class M
{
N n;
public:
M() : n()
{
}
};
It is incorrect to say that the destructor deletes members. It invokes the destructor of each member (and base class), which for built-in types (like pointers) means doing nothing.
Matching news with deletes is your responsibility (either manually, or with the help of smart pointers).
Your argument might seem sound but that's not how things work for pointers.
n is actually being destructed but, what this means is that the N* destructor is being called which, it does NOT destruct whatever object n is pointing to. Think of the N*'s destructor as if it were an int's destructor. It deletes its value, the same happens for a pointer, it deletes the address it is pointing to, but it doesn't need to delete whatever object is located at the address you just deleted.
I think you may be confused about levels of indirection here. When an instance is destroyed, each data member does indeed get destroyed along with it. In your case, when an M is destroyed and M::~M() is called, its variable n really is destroyed. The problem is that n is a N *, so while the pointer is destroyed, the thing it points to is not.
delete does not work like this. Consider your simple statement:
delete n;
The above statement destroys the thing that n points to, which is an object of type N. It does not destroy n itself, which is an N * pointer.
There is a very good reason that M::~M() does not automatically call delete n; which is this: the N object referred to might be shared between several M objects, and if one M were destroyed, the rest would lose the N they were pointing at, leaving horrible dangling pointers everywhere. C++ does not attempt to interpret what you meant to do with your pointers, it just does what you told it to do.
In short, M really is destroying all of its members when it is destroyed, it's just that this destruction doesn't do what you think it should do. If you want a pointer type which takes ownership of an object and destroys it when the pointer is destroyed, look at std::auto_ptr.
The default destructor looks like this:
~M()
{
}
The default destructor does not insert code to do anything with pointed-to things. What if you had n pointing to a stack variable? Automatically inserting a delete n would crash.
The default destructor calls the destructor on each member of the class (member.~T()). For a pointer, that's a no-op (does nothing), just like myint.~int() does nothing, but for member classes with defined destructors, the destructor is called.
Here's another example:
struct MyClass {
public:
MyClass() { .. } // doesn't matter what this does
int x;
int* p;
std::string s;
std::vector<int> v;
};
The default destructor in reality is doing this:
MyClass::~MyClass()
{
// Call destructor on member variables in reverse order
v.~std::vector<int>(); // frees memory
s.~std::string(); // frees memory
p.~int*(); // does nothing, no custom destructor
x.~int(); // does nothing, no custom destructor
}
Of course, if you define a destructor, the code in your destructor runs before the member variables are destroyed (obviously, otherwise they would not be valid!).
Try avoiding using pointers. They are last resort elements.
class N {
public:
~N() {
std::cout << "Destroying object of type N";
}
};
class M {
public:
M() {
// n = new N; no need, default constructor by default
}
// ~M() { //this should happen by default
// delete n;
// }
private:
N n; // No pointer here
};
Then use it this way
main(int, char**)
{
M m;
}
This will display Destroying object of type N
I think you could benefit from a very simple example:
int main(int argc, char* argv[])
{
N* n = new N();
} // n is destructed here
This will not print anything either.
Why ? Because the pointer (n) is destructed, not the object pointed to *n.
Of course, you would not want it to destroy the object pointed to:
int main(int argc, char* argv[])
{
N myObject;
{
N* n = &myObject;
} // n is destructed here, myObject is not
myObject.foo();
} // myObject is destructed here
You should remember that unlike languages like C# or Java, there are 2 ways to create objects in C++: directly N myObject (on the stack) or via new like in new N() in which case the object is placed on the heap and YOU are reponsible for releasing it at a later time.
So your destructor destroys the pointer, but not the object pointed to. Allocate the object without new (and without using a pointer) or use a Smart Pointer if you want it to be automatic.
M destructor should have 'delete n'.
Since you are using new to create instance, it won't delete by default.
class N {
public:
~N() {
std::cout << "Destroying object of type N";
}
};
class M {
public:
M() {
n = new N;
}
// ~M() { //this should happen by default
// delete n;
// }
private:
N* n;
};
and now the expectation is :
M* m = new M();
delete m; //this should invoke the default destructor
It will only happen, if the class M is derived from N:
class M: Class N {
...
Only in this situation,
M* m = new M()
will call constructor of N and then constructor of M, where as
delete m;
will automatically call destructor of M first and then N