string * str=new string;
delete str;
when I delete 'str' which points to an object, do two destructors get called - one for the pointer itself, and one for the object it points to?
What would the pointer's destructor do?
delete just causes the object that the given pointer is pointing at to be destroyed (in this case, the string object. The pointer itself, denoted by str, has automatic storage duration and will be destroyed when it goes out of scope like any other local variable.
Note, however, that non-class types do not have destructors. So even when you use delete with non-class types, no destructor is called, but when the pointer goes out of scope, it gets destroyed as normally happens with any other automatic variable (means the pointer just reaches the end of its lifetime, though the memory pointed to by the pointer is not deallocated until you use delete to explicitly deallocate it.).
The pointer it self doesn't been destructed by the delete statement. but as any scope variable it's been destroyed when the scope ends.
Example:
void Function()
{
string * str=new string;
delete str; // <-- here the string is destructed
} // <-- here the pointer is "destructed", which is mean it's memory freed from the stuck but no actual destruction function is called..
The concept of destructor is applicable only to objects (i.e. entities defined with class or struct), not to plain types, like a pointer is. A pointer lives just like a int variable does.
when I delete 'str' which points to an object, do two destructors get called - one for the pointer itself, and one for the object it points to?
No. delete takes a pointer argument. It destroys the object that's pointed to (using its destructor, if it has one, and doing nothing otherwise), and deallocates the memory that's pointed to. You must previously have used new to allocate the memory and create the object there.
The pointer itself is not affected; but it no longer points to a valid object, so you mustn't do anything with it. This is sometimes known as a "dangling pointer".
What would the pointer's destructor do?
Nothing. Only class types have destructors.
The destructor for a raw pointer, like your example of std::string*, is trivial (just like the destructors for other primitive types: int, double, etc.)
Smart pointer classes have non-trivial destructors that do things like free resources, adjust reference counts, etc.
I like the simplification you get from the notion that every type has a destructor. That way you don't have a mental glitch with a template that explicitly destroys a stored value, even if the type of that stored value is an int or a pointer:
template <class T> struct wrapper {
unsigned char data[sizeof(T)];
wrapper(T t) { ptr = new (data) T; }
~wrapper() { (T*)&data->~T(); } // ignore possible alignment problem
wrapper<int> i(3);
However, the destructors for ints and pointers are utterly trivial: they don't do anything, and there is no place you can go to see the definition of the destructor, because the definition doesn't exist. So it's also reasonable to say that they don't have destructors.
Either way, when a pointer goes out of scope it simply disappears; no special code runs.
Related
I'm wondering if the following is undefined?
int main()
{
struct Doggy { int a; ~Doggy() {} };
Doggy* p = new Doggy[100];
p[50].~Doggy();
p[50].a = 3; // Is this not allowed? The destructor was called on an
// object occupying that area of memory.
// Can I access it safely?
if (p[50].a == 3);
}
I guess this is generally good to know, but the reason I'm specifically wanting to know is that I have a data structure consisting of an array, where the buckets can be nullable by setting a value, kind of like buckets in a hash table array. And when the bucket is emptied the destructor is called, but then checking and setting the null state after the destructor is called I'm wondering if it's illegal.
To elaborate a little, say I have an array of objects and each object can be made to represent null in each bucket, such as:
struct Handle
{
int value = 0; // Zero is null value
~Handle(){}
};
int main()
{
Handle* p = new Handle[100];
// Remove object 50
p[50].~Handle();
p[50].value = 0; // Set to null
if (p[50].value == 0) ; // Then it's null, can I count on this?
// Is this defined? I'm accessing memory that was occupied by
// object that was destroyed.
}
Yes it'll be UB:
[class.dtor/19]
Once a destructor is invoked for an object, the object's lifetime ends; the behavior is undefined if the destructor is invoked for an object whose lifetime has ended ([basic.life]).
[Example 2: If the destructor for an object with automatic storage duration is explicitly invoked, and the block is subsequently left in a manner that would ordinarily invoke implicit destruction of the object, the behavior is undefined. — end example]
p[50].~Handle(); and later delete[] p; will make it call the destructor for an object whose lifetime has ended.
For p[50].value = 0; after the lifetime of the object has ended, this applies:
[basic.life/6]
Before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that represents the address of the storage location where the object will be or was located may be used but only in limited ways. For an object under construction or destruction, see [class.cdtor]. Otherwise, such a pointer refers to allocated storage ([basic.stc.dynamic.allocation]), and using the pointer as if the pointer were of type void* is well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in limited ways, as described below. The program has undefined behavior if:
6.2 - the pointer is used to access a non-static data member or call a non-static member function of the object
Yes, it's mostly. Handle::value is just an offset to a pointer of type Handle, so it's just going to work wherever you point it to, even if the containing object isn't currently constructed. If you were to use anything with virtual keyword, this would end up broken though.
p[50].~Handle(); this however is a different beast. You should never invoke destructors manually unless you have also explicitly invoked the constructor with placement new. Still not illegal, but dangerous.
delete[] p; (omitted in your example!) is where you end up with double-destruction, at which point you are well beyond UB, straight up in the "it's broken" domain.
I would like to have a class contain a std::unique_ptr initialized by the constructor then used elsewhere in the class.
So I've got a class that contains a std::unique_ptr like this:
class ObjectA
{
public:
ObjectA();
~ObjectA();
void SomeFunction();
private:
std::unique_ptr<ObjectB> myPointer;
}
Then in the class's source file myPointer is setup in the constructor and used in SomeFunction().
ObjectA::ObjectA()
{
ObjectC objectC;
myPointer = std::move(std::unique_ptr<ObjectB>(objectC.getPointer())); //setup pointer
}
ObjectA::~ObjectA() {}
void ObjectA::SomeFunction()
{
//use myPointer here
}
The problem though, is that I can't use myPointer in SomeFunction(), and here's why.
Obviously myPointer must be allocated on the heap to assure it doesn't get destroyed when the constructor is done executing. Assume that ObjectC and consequentially it's functions are from an external library. When I call ObjectC::getPointer() the pointer that's return is probably allocated on the stack apposed to the heap. Now I assume this is the case because right after the constructor has finished executing I get an error.
Basically I'm relying on a function to give me a pointer with wich I can then use elsewhere. However, the function allocates the object on the stack instead of the heap.
Is there some special way to solve this problem, maybe with a double pointer? Or will I just have to call ObjectC::getPointer() every time I want to use the pointer inside each execution block? If I had lots of functions inside ObjectA which rely on myPointer then calling ObjectC::getPointer() per function would be redundant, but I don't know if there is a better way to fix this, and I feel like a function (ObjectC::getPointer()) shouldn't force me into that redundancy.
When you call ObjectC::getPointer(), you don't just get "a" pointer. The function must specify what operations are valid on the pointer, and in particular how it should be disposed.
Usually, that would be delete, but it could also be e.g. fclose. You'll have to read the documentation. If the lifetime of the returned pointer matches that lifetime of objectC, then the lifetime of objectC should match myPointer. So it probably should be a member, and that in turn means that myPointer might be redundant. You could just substitute private: ObjectB& getB() { return *myObjectC.GetPointer(); }
struct Temp
{
CString one;
CString two;
};
class Foo
{
public:
Temp obj;
void somewhere();
}
void Foo::somewhere()
{
void* pData = static_cast<void*>(&obj);
OwnMethod(pData); // void OwnMethod(void*);
}
The question is:
Should I create obj on heap or this situation isn't dangerous (passing local class objects pointer)?
If OwnMethod(pData) stores the pointer somwhere for later use, that later use is not possible anymore, once the object on which Foo::somewhere() is called is destroyed.
If OwnMethod(pData) only access the pointed to data, you are safe.
The member variable will last as long as the Foo object, so the pointer will be valid during the call to OwnMethod.
If that function stores a copy of the pointer somewhere, and something else uses that pointer later, then there is a danger that it might be accessed after the Foo (and therefore the pointer's target) have been destroyed. There are various ways to prevent that; as you say, one is to dynamically allocate the object, and then transfer or share ownership when it's passed to OwnMethod. Smart pointers, such as std::unique_ptr and std::shared_ptr, are a very good way to track ownership of dynamic objects.
Wow, a lot of issues.
A complex object should't be passed to anything taking a void*.
Who wrote OwnMethod?
Why doesn't it take a pointer of type Foo*?
In fact why doesn't it take a reference of type Foo&?
If OwnMethod() may be required to accept objects of several different types then it should take a base class pointer or reference and use polymorphism.
However as far as the lifetime arguments go - obj will exist as long as the wrapping class does, so if the pointer is not used beyond the scope of OwnMethod this is ok. If OwnMethod causes the pointer to be stored elsewhere beyond Foo's lifetime then you have an issue, and maybe obj should be allocated on the heap. (And it might not even be appropriate for it to be a member of Foo at all.)
When the object a is destroyed, is the personsInHouse map also destroyed or I need to destroy it in destructor? Will it create memory leak if I don't?
class A {
public:
map<unsigned int, unsigned int> personsInHouse;
};
int main(){
A a;
A.hash[10] = 23;
};
The lifetime of personsInHouse is automatic because you are storing it by value, and its lifetime is the lifetime of the parent object. Because you create a by value, its destructor is called when it goes out of scope, and the destructor of an object automatically calls the destructors of the objects it contains. So you do not need to destroy personsInHouse, like you do not need to destroy a.
If personsInHouse was a pointer and you created a map<unsigned int, unsigned int> in dynamic storage with new and stored a pointer to it in personsInHouse, then you would need to manually deallocate the memory that personsInHouse was pointing to in the destructor of A via delete. But that's not the case in the code you posted.
What you have done is the good way to do it: prefer to store every object that you can by value so that you don't have to worry about lifetime management of dynamic objects.
Yes, it is. When the destructor of a class is run, the destructors of all its members are run. To be precise, the order is:
Body of the destructor is run
All members, in reverse order of construction, are destructed
All non-virtual base classes, in reverse order of construction, are destructed
All virtual base classes, in reverse order of construction, are destructed
In general, if you don't have pointers, you can expect to also not have memory leaks. This is not always the case: you may be using a leaky function, or some function may be performing dynamic allocation and then returning a reference to the object. The situation can be further improved by using smart pointers.
A useful technique for avoiding memory leaks in C++ is RAII: all standard containers follow it, which is why there's no need to explicitly clear() a container before it goes out of scope. The basic principle is to make classes clean up all their resources in their destructors, and then make dedicated classes for that so that most of your classes need not worry about it.
Do note that "class members" are strictly non-static members defined at class scope. If you have
struct S {
int* p;
};
then p is the only member of S, and when S goes out of scope, p will be destroyed (which doesn't generally involve anything happening, except perhaps an adjustment of the stack pointer). If you at some point do S s; s.p = new int; then p will still be the only member, and the object pointed to by p will not be one, and will therefore not be destroyed when s goes out of scope. For that to happen, you will need to manually do delete s.p;, which corresponds to the general rule of every new needing to have a corresponding delete (idem for new[] and delete[]).
I have a basic question on destructors.
Suppose I have the following class
class A
{
public:
int z;
int* ptr;
A(){z=5 ; ptr = new int[3]; } ;
~A() {delete[] ptr;};
}
Now destructors are supposed to destroy an instantiation of an object.
The destructor above does exactly that, in freeing the dynamically alloctaed memory allocated by new.
But what about the variable z? How should I manually destroy it / free the memory allocated by z? Does it get destroyed automatically when the class goes out of scope?
It gets "destroyed" automatically, although since in your example int z is a POD-type, there is no explicit destructor ... the memory is simply reclaimed. Otherwise, if there was a destructor for the object, it would be called to properly clean-up the resources of that non-static data member after the body of the destructor for the main class A had completed, but not exited.
z is automatically destroyed. This happens for every "automatic" variable. Even for pointers like int*, float*, some_class*, etc. However, when raw pointers are destroyed, they are not automatically deleted. That's how smart pointers behave.
Because of that property, one should always use smart pointers to express ownership semantics. They also don't need any special mentioning in the copy / move constructor / assignment operator, most of the time you don't even need to write them when using smart pointers, as they do all that's needed by themselves.
Destroying an object will destroy all the member variables of that object too. You only need to delete the pointer because destroying a pointer doesn't do anything - in particular it doesn't destroy the object that the pointer points to or free its memory.
It does, in fact, get automatically destroyed when the class goes out of scope. A very good way to guess if that's the case is that there's no * after its declaration.
For PODS (plain old data types) like ints, floats and so on, they are automatically destroyed. If you have objects as data members (e.g. std::string aStr;), their destructors will be automatically called. You only have to manually handle memory freeing (like above) or any other manual object or data cleanup (like closing files, freeing resources and so on).