error: double free or corruption (out)

Hello
i have this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <vector>
#include <algorithm>
#include <iostream>

int main(){
    std::vector<int> vec{0, 1, 2};
    std::vector<int>::iterator it = std::max_element(vec.begin(), vec.end());
    std::vector<int> vec2{3, 4, 5};
    vec.insert(vec.end(), vec2.begin(), vec2.end());
    vec.erase(it);
    for (auto &n : vec){
        std::cout << n << std::endl;
    }
}


but when i execute it, I get this output:
1
2
3
4
5
double free or corruption (out)
Aborted


first question: why this corruption error and how to fix it?
second: why is the output "1 - 2 - 3 - 4 - 5", and not "0 - 1 - 3 - 4 - 5"!? since the iterator "it" points to the max value in vec, I would expect to value 2 being erased, not 0.
I'm using g++ (Debian 9.2.1-8) 9.2.1 20190909
and for some reason, if I execute this code online (in cpp.sh), I get no errors about memory corruption, but the output is still wrong.

what could be wrong? thanks for the help!
Last edited on
http://www.cplusplus.com/reference/vector/vector/insert/
Iterator validity
If a reallocation happens, all iterators, pointers and references related to the container are invalidated.
vector.insert can invalidate iterators. Using this invalid iterator is like using an invalid pointer; undefined behavior.

See: https://en.cppreference.com/w/cpp/container/vector/insert
cppreference wrote:
Causes reallocation if the new size() is greater than the old capacity(). If the new size() is greater than capacity(), all iterators and references are invalidated. Otherwise, only the iterators and references before the insertion point remain valid. The past-the-end iterator is also invalidated.
Last edited on
The problem is line 7. After a vector is modified you cannot use the iterator proviously obtained.

Instead of using the iterator you may use the distance (which does not change):

http://www.cplusplus.com/reference/iterator/distance/?kw=distance
geez... is it invalidated because the vector is moved in memory when the size changes?

so is there any way to keep a reference to number 2 in this case? using deque would be the way, or is there any better approach?
thanks
Use std::distance as coder777 said, or, simply move line 10 above line 9.
Keeping references to an element of a vector that is changing in size is asking for trouble.
There are other solutions, but it all depends on the use case. For example, in a program I have, I have a dynamically growing vector objects, where each object can contain an array. I actually dynamically allocate each element and have my vector be a vector of pointers. But that might be overkill depending on the application.
Last edited on
okk, I see.. thanks everybody for the help :)
One could make sure that the vector does not need realloc during the insert:
1
2
3
4
5
std::vector<int> vec{0, 1, 2};
std::vector<int> vec2{3, 4, 5};
vec.reserve( vec.size() + vec2.size() );
std::vector<int>::iterator it = std::max_element( vec.begin(), vec.end() );
vec.insert( vec.end(), vec2.begin(), vec2.end() );


One could seek the max from the elements of the first vector:
1
2
3
4
5
std::vector<int> vec{0, 1, 2};
std::vector<int> vec2{3, 4, 5};
auto first = vec.size();
std::vector<int>::iterator it = std::max_element( vec.begin(), vec.begin() + first );
vec.insert( vec.end(), vec2.begin(), vec2.end() );
Topic archived. No new replies allowed.