Difference between vector insert and assign - c++

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.

Related

C++: Does vector of pointer elements automatically deallocate dynamic memory pointed by each pointer upon destruction?

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.

Will stl container free memory after deleting heap based object?

I am fairly new to C++, so I have got this question:
I am know that stl containers do not deallocate memory from heap pointers, one need to deallocate it himself, and I know that containers call destructors of objects being deleted, but say we have this abstract code:
Object* pObject = new Object();
vector<Object>[i] = *pObject;
Now after vector gets destroyed will it actually free memory pObject pointing to? Or it will just call the destructor of Object, making it invalid and leaving the memory marked as "occupied" for memory manager?
Thank you.
You're not actually placing pObject in the std::vector, you're placing a copy of what pObject points to. Therefore the object in the std::vector and *pObject will be totally distinct.
When the std::vector is destroyed, it will call the destructor of this copy of the object, but your original object will be unaffected. I.e. pObject will still point to a valid object, and will have to be delete'd separately.
You have a vector<Object> hence, a vector of Object not Object*. The new is not needed at all in this case.
Standard containers will manage the memory they allocate, not yours. If you have a container of pointers to objects you have newed, then you will need to delete them before the container goes out of scope.
If you want the container (with some allies) to manage the memory for you, use std::shared_ptr or std::unique_ptr. There are boost and tr1 equivalents if you compiler does not yet support C++11.
std::vector<std::shared_ptr<Object>> container;
The container will manage the smart pointers, and the smart pointers in turn manage the memory.

Vector of pointers, elements of which initialized with new: what happens when assigning a new value?

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.

Vector and queue of pointers data exchange: deep and shallow copies

In my code I have a vector of pointers to objects of SomeClass and a (custom comparison) vector-based priority queue that contains pointers to objects of SomeClass:
std::vector<SomeClass*> my_vector;
std::priority_queue<SomeClass*, vector<SomeClass*>, CustomCompare> my_queue;
Initially my_vector is empty and my_queue is full. Gradually my_queue is emptied into my_vector like this:
my_vector.push_back(my_queue.top());
my_queue.pop();
My question is: Will my_queue.pop() delete the memory that was allocated to the SomeClass object that was pushed back to my_vector therefore causing the element of my_vector to be a dangling pointer? Or otherwise, does the vector make a deep or a shallow copy of the object pointed to by the pointer returned by my_queue.top()?
No deletions will be made. The only thing being copied/removed/pushed_back are pointers. The objects these point to remain alive, provided they have been dynamically allocated. In that case, you will have to do the clean-up yourself.
Depending on the behaviour desired, you may want to use smart poitners to avoid manual memory management, store SomeClass objects instead of pointers, or leave things as they are and make sure to make a cleanup at the end. Bear in mind that it can be difficult to guarantee that your program will safely get to the point where the memory is released, which is one reason smart pointers are preferred over raw pointers to dynamically allocated objects.
my_queue.pop() will only delete the object stored in the queue; in this case, the pointer itself, not the object pointed by the pointer. So you are fine here.
Mandatory remark: consider using smart pointers instead of raw pointers.
Both the queue and the vector only contain pointers. Unless you use smart pointers or shared pointers neither the destructor of the queue nor that of the vector will free the memory.
No. Since they store pointers, they will copy and destroy pointers (which is a no-op). There's no magic involved. If they never store a pointer to the same object simultaneously you may want to make then store unique_ptrs if you want them to destroy the objects in the end. Alternatively you can store the actual objects in a third vector (vector<SomeClass>), and maintain the vector and queue of pointers separately.
You're storing pointer to SomeClass object everywhere, so no my_queue.pop() just removes the pointer from queue and your object is ok, and you will store a copy of pointer to vector, not a deep copy.

Will this memory be freed properly?

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.