I have a pair pointer let us suppose std::pair< A*, B* >* pointerpair. I allocated it memory and after using the pair i call delete pointerpair.
Will it also call delete A and delete B and will be freeing the memory completely ?
if i only call delete A and delete B but no delete pointerpair then is it a memory leak ?
No.
However, in STL and Boost, there is a family of classes called smart pointers, which can automatically delete the objects whose pointers are stored in them. However, outside those smart pointer classes, any raw pointers stored in STL / Boost containers are simply treated as pointers. For example, you can define a set of raw pointers to strings. This set will be sorted using the pointer values, not the lexicographical order of the strings (unless you supply your comparison functor).
No. It won't do it automatically. You have to delete it explicitly.
Related
The title is self explanatory - does the standard vector implementation take care of deallocating dynamic memory pointed to by all the pointers that are in the vector?
No. When you destroy a std::vector it destroys all its elements (calls their destructor) and then deallocates the storage used by the objects. But a (raw) pointer does not have a destructor - destroying it does not deallocate the object it points to - it just destroys the storage used to hold the pointer itself.
If you had had a vector of smart pointers (std::unique_ptr or std::shared_ptr) then it would be a different matter. Those classes do have destructors and do deallocate what they point to upon destruction (unique_ptr always, shared_ptr if it's the last object pointing to the contained object, otherwise it just decrements its reference count).
Note: a std::unique_ptr is a very thin wrapper around a raw pointer, that is designed to optimize away completely. So, using it should have zero overhead over a raw pointer when optimization is enabled. So it'll give you the semantics you want with no overhead compared to doing the manual memory management - manually.
No it doesn't.
If you want "self-deleting" pointers use smart pointers (std::unique_ptr or std::shared_ptr) or (depending on what the pointers are used for) a container such as std::vector, std::array or std::string.
No it doesn't. Containers are not reponsible of the memory management of raw pointers. It would be possible to automatically deallocate your pointer elements if they were smart pointers (RAII : https://fr.wikipedia.org/wiki/Resource_acquisition_is_initialization)
You can see a pointer as a simple integer. Its value represents a memory address. When the vector pointer element is deleted, the bytes allocated to store this address are freed. Thus, the memory address pointed by the pointer is lost (No more reference to it = memory leak).
Containers will never manipulate your instances (Free pointers, modify content). It can only call constructors (Specified one, copy, move...) and the destructor.
Depends on the what pointers the vector is containing, for raw pointers like
std::vector<Something*>
no, you have to do the cleanup yourself.
If the vector contains smart pointers, on the other hand, like std::unique_ptr
std::vector<std::unique_ptr<Something>>
then the cleanup is taken care of for you.
Long story short: try to use smart pointers.
I have a series of questions to ask.
What is the correct way to destroy a vector of pointers?
I know the vector class has the default destroyer but I do not know if the pointers change something.
An array containing object pointers in its destruction requires the simple command: Delete [] pointname?
Or do I have to do some other operation first on pointers?
A list or vector of object pointers to be emptied requires a simple command: list_name / vector_name.clear (); Or do some other operations on the pointers first?
1) What is the correct way to destroy a vector of pointers? I know the vector class has the default destroyer but I do not know if the pointers change something.
If you have manually allocated the pointers in the vector and you want to delete (deallocate and destroy) them when the vector is destroyed, you should automate it with std::unique_ptrs
{
std::vector<std::unique_ptr<int>> vec;
vec.push_back(std::make_unique<int>(1));
vec.push_back(std::make_unique<int>(2));
}
when the vector is destroyed, the integers will be destroyed as well. If you are curious as to how this works and are not familiar with code like this, read up on RAII
2) An array containing object pointers in its destruction requires the simple command: Delete [] pointname? Or do I have to do some other operation first on pointers?
If you have allocated that array with new[] then you can call delete[] on that array. Keep in mind that this will not call delete on the integers individually, it will just deallocate the memory allocated for the array. If you want to deallocate the integers as well use unique_ptr as in the above example
3) A list or vector of object pointers to be emptied requires a simple command: list_name / vector_name.clear (); Or do some other operations on the pointers first?
This will clear the container but not free the pointers. See the above two points.
In answer to your second question, using delete[] and then the name of your array of pointers is satisfactory with no additional steps. delete[] just takes the array of pointers and causes the kernel to 'realise' the memory locations they point to so other operations can 'use' (write-over the data previously in) those locations. This is all you need to do. Now other operations can request memory and the kernel is free to 'give away' those locations.
I read that the assign method clears the vector target indexes before assigning anything to it.Does that mean if we have a vector such as:
vector<foo*> somevector;
then the assign method would actually delete foo* before copying data to the target indexes.
then the assign method would actually delete foo* before copying data to the target indexes.
No, it will only delete pointer itself but will not delete objects which pointers pointing to.
You need to be careful when you use raw pointers in STL container. If you dynamically allocates elements in somevector, you endup leaking memory.
More practice way is to use smart pointers in STL container, dynamically allocated memory will be de-allocated in below case:
std::vector<std::unique_ptr<foo>> somevector;
No. std::vector will never call delete on stored pointers. It will simply destroy the object. In the case of a class objects with non-trivial destructors, destroying consists of calling that destructor. In the case of pointers, or any other trivially destructible object, destroying consists of doing nothing.
No, standard containers containing pointers to objects don't ever call delete on the pointers - you are responsible for doing this if/when necessary. This is why storing pointers is a bad idea.
I have a vector of pointers like this:
std::vector<foo*> stuff;
I initialize each element with a new foo();:
My question is what happens when I reassign one of the vector's elements, say
stuff[3] = new foo();
Am I leaking memory and should I have called delete[] before this? Is this a case where I should be using smart pointers? (never have so far)
Normally I would not be using new but I 'm learning Qt and this is how it seems done in the examples. Qt seems to have smart pointers of its own; should I be using one of those?
Thanks.
yes, you leak when stuff get destructed leaving all those dynamic allocated foo undeleted and unreachable unless you iterate through the vector and call delete.
typically when you want a vector of pointer you use std::shared_ptr
std::vector<std::shared_ptr<foo>> stuff;
stuff[3] = std::make_shared<foo>();
this could potentially be a performance bottleneck if the vector is huge and you try to copy it( then perhaps you want to wrap it in another shared_ptr ), but if you are only accessing the element of the vector it eliminate all the problems about who delete what and when that come with the raw pointer approach.
My question is what happens when I reassign one of the vector's elements, say
stuff[3] = new foo();
Am I leaking memory
Yes, you're leaking memory. The vector doesn't know who's responsible for owning the object you allocated. It's can't tell the difference between:
stuff[3] = new foo();
and
foo f;
stuff[3] = &f;
Therefore it will not any cleanup for you.
and should I have called delete[] before this?
Not quite. delete[] is used to destroy a dynamically allocated array; it's what you would use to destroy something allocated via new[]. To destroy something allocated via plain new, you should use plain delete.
Is this a case where I should be using smart pointers? (never have so far)
Yes. If you used std::shared_ptr<foo> (or boost::shared_ptr<foo> if you can't use C++11), then the std::shared_ptr object would take responsibility for deleteing the object for you.
I don't see any relation with Qt in your code. memory leak occurs when don't call delete after you allocated the object with new. what you should do it to run a loop on that vector and call delete on each item.
a vector makes a copy of the object and stores the copy. Now in your example, the vector is of the type foo*. So when it is passed a pointer to foo, vector makes a copy of the pointer, not the foo itself. Now when you reassign and do other stuff, the copy of the pointer is freed by vector, but not the memory pointed by the pointer. Imagine you have a vector of keys, so the vector makes a copy of key passed to it, and frees the copy of the key. But it never touches the lock for which the key is. That you need to handle yourself. You can get the value and free the element yourself before reassigning.
If foo are QObjects then assign to each a parent (which will be responsible for deleting them - although they could be deleted manually too). And in that case, do not use smart pointers as that will create ownership conflicts.
Given an STL vector of pointers, each element has to be deallocated before destroying the vector itself. Is there any technical implication that prevents the STL library for doing it automatically?
Thanks
The reason the STL doesn't do it for you is that it can't know whether or not it's supposed to. You might have a vector of pointers to arrays (in which case it needs to do delete[]), of pointers to regular objects (in which case it would need to do delete), or possibly memory from some custom allocator. Those pointers could also be shared with some other objects, in which case deleting them would cause those other objects to point at garbage data, leading to undefined behavior. Those pointers could also be to stack-allocated memory, in which case no deallocation is necessary.
you can store there pointers that shouldn't be deleted when vector is destructed
use vector of smart pointer (e.g. boost::shared_ptr) to receive automatic deallocation
If a vector contains pointers, it does not mean that the pointers point to dynamic memory. And if they do, should delete or delete[] be applied to each pointer? And what if the pointers points to objects created using placement new? All these question should be answered by the programmer, not by the library.