0

The pains of compiled libraries is never knowing exactly how the memory is managed. I'm lead to believe that vector's elements are placed on the heap unless explicity told not to.

Being placed on the heap, it obviously needs to be deleted when it is no longer used, which seems to happen when the vector object is deleted.

The question is when the at(#) or operator[] is called does it delete the memory being replaced?

For example:

std::vector<string> secretlyAnArray(5);
secretlyAnArray.at(0) = std::string("Does this memory leak?");
secretlyAnArray.at(0) = std::string("When I overwrite the object?")

Happy to learn better methods to replace data at a specific index of a vector, or just pointing at the documentation that explains it.

Edit 2: After the helpful comments of Anis and Daniel which are much appreciated; it appears that at(#) returns a reference, which then standard reference rules apply rather than governed by the behavour of vector.

Bellona
  • 1
  • 1
  • at returns a reference to the object at a given position , so your object will assigned or moved – Anis Belaid Nov 08 '21 at 07:50
  • @AnisBelaid Ah so it's just updating the data rather than replacing the object? So if you were using a custom class it would break horribly if you had a copy constructor, but not the the assign & move operators? (If a shallow copy wasn't enough) – Bellona Nov 08 '21 at 07:56
  • yep it won't work, there are also no memory leaks as temp object are destroyed outside the scope – Anis Belaid Nov 08 '21 at 07:58
  • _"I'm lead to believe that vector is placed on the heap unless explicity told not to."_ — A vector object is placed wherever you create it. In case of automatic storage duration (basically function local non-static variable), it will be on the stack with typical implementations. But the vector elements are always on the heap (at least with the default allocator). – Daniel Langr Nov 08 '21 at 08:12
  • In general if you've used `new` you need to use `delete` (or pass your object into something that'll do that for you) otherwise the classes that have allocated memory should deallocate it automatically on destruction – Alan Birtles Nov 08 '21 at 08:17
  • After EDIT: No, in both cases, move assignment operator will be called, since the right-hand-side expressions are both rvalues. With `std::move`, you are just creating an rvalue from the already existing rvalue. Also note that the move-assignment operator doesn't have a `const` parameter (rvalue reference). – Daniel Langr Nov 08 '21 at 08:45

1 Answers1

1
std::vector<std::string> secretlyAnArray(5);
secretlyAnArray.at(0) = std::string("Does this memory leak?");
secretlyAnArray.at(0) = std::string("When I overwrite the object?")

This code assigns an object of type std::string to another object of type std::string. The std::vector itself isn't at all involved in this assignment. Here, it just provides a reference to the destination (assigned-to) object.

What does assignment do for a given type depends on its definition. There is no generic answer. For instance, with std::string, when you copy/move-assign, the original content of the destination object (its string of characters) needs to be "destroyed". std::string does it for you, so, you don't need to care about it. It means that if the string is "long" (with regard to short string optimization; SSO), the memory will be correctly deallocated, if needed.

Daniel Langr
  • 22,196
  • 3
  • 50
  • 93
  • Yes, you are 100% correct abotu the vector. I will change my wording inthe question as I was indeed refering to the elements of the vector. Interesting; when you are talking about the memory being destroyed are you refering to the classes destructor or something more abstract such as the way smart pointers manage when to call their destructors? Or more simply put, is there a scenario you would need to call delete on the elements of a vector before reassigning the value? – Bellona Nov 08 '21 at 08:29
  • Is calling vector.at(type) the equavalent of calling: type::operator=(const type& other) or type::operater=(const type&& other) depending on whether given an L or R type value? – Bellona Nov 08 '21 at 08:35
  • @Bellona Again, there is no generic answer. For instance, with _copy-and-swap_ solution of the assignment operation, a destructor call is involved. Which should release all resources owned by the object. However, with `std::string`, if the _capacity_ of the destination object is able to store the string owned by the source object, there is no need for (de)allocation. The assignment operator can use the existing allocated buffer to copy the string into. – Daniel Langr Nov 08 '21 at 08:39
  • _"Is there a scenario you would need to call delete on the elements of a vector before reassigning the value?"_ — No, you cannot "delete" vector's elements explicitly. A vector manages its elements for you, including their destruction when it is needed. – Daniel Langr Nov 08 '21 at 08:40
  • @Bellona No, it is not equivalent. As already mentioned, `vector.at()` only returns a reference to the element. It does not represent any operation with its content. Calling `vector.at()` by itself doesn't have any effect. – Daniel Langr Nov 08 '21 at 08:42
  • So it's more to do with references than vector at all. Is there any reading you would recommend to learn more about references and the nature or their use? – Bellona Nov 08 '21 at 08:45
  • @Bellona Check this post: [The Definitive C++ Book Guide and List](https://stackoverflow.com/q/388242/580083). Any serious introductory C++ learning material should explain references and their relation to object content copying/moving operations. – Daniel Langr Nov 08 '21 at 08:48
  • thanks you rock! I'll definitely give it a good read. – Bellona Nov 08 '21 at 08:50