std::vector<std::vector<int>> push_back gives heap-buffer-overflow

Patryk

I am trying to solve hackerrank's even tree task with the following piece of code to read the input (std::cin replaced with custom string data to have input and program code in one place here):

#include <iostream>
#include <vector>
#include <sstream>

int main()
{
  std::istringstream input( "10 9\n2 1\n3 1\n4 3\n5 2\n6 1\n7 2\n8 6\n9 8\n10 8\n");
  std::cin.rdbuf(input.rdbuf());

  int n,m;
  std::cin >> n >> m;

  std::vector<std::vector<int>> v(n);

  //std::vector<std::vector<int>> v(n, std::vector<int>(n, -1));

  int ui, vi;
  while (m--)
  {
    std::cin >> ui >> vi;
    v[ui].push_back(vi);
    v[vi].push_back(ui);
  }
}

The second number will be the number of edges ( subsequent number pairs ) so I can predict how many element in the vector I will need.

This code gives me the following sanitizer error (the same error with the commented line):

clang++-3.6 -g -Wall -fsanitize=address --std=c++11 main.cpp && ./a.out
=================================================================
==11606==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x611000009ff8 at pc 0x0000004e0beb bp 0x7ffd09cb9ab0 sp 0x7ffd09cb9aa8
READ of size 8 at 0x611000009ff8 thread T0
    #0 0x4e0bea  (PATH/a.out+0x4e0bea)
    #1 0x4dfa28  (PATH/a.out+0x4dfa28)
    #2 0x7f407bd75ec4  (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #3 0x438227  (PATH/a.out+0x438227)

0x611000009ff8 is located 8 bytes to the right of 240-byte region [0x611000009f00,0x611000009ff0)
allocated by thread T0 here:
    #0 0x4de672  (PATH/a.out+0x4de672)
    #1 0x4ecf8a  (PATH/a.out+0x4ecf8a)
    #2 0x4eccd5  (PATH/a.out+0x4eccd5)
    #3 0x4eca90  (PATH/a.out+0x4eca90)
    #4 0x4ec70f  (PATH/a.out+0x4ec70f)
    #5 0x4ea89a  (PATH/a.out+0x4ea89a)
    #6 0x4e047a  (PATH/a.out+0x4e047a)
    #7 0x4df8f2  (PATH/a.out+0x4df8f2)
    #8 0x7f407bd75ec4  (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)

Shadow bytes around the buggy address:
  0x0c227fff93a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c227fff93b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c227fff93c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c227fff93d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c227fff93e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c227fff93f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fa[fa]
  0x0c227fff9400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c227fff9410: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c227fff9420: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c227fff9430: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c227fff9440: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==11606==ABORTING

What am I missing here?

EDIT

Ok so I have found one of the solutions which would be to emplace_back a default std::vector<int> on v:

std::vector<std::vector<int>> v(n);
for (int i = 0; i < n; ++i) v.emplace_back();

But why didn't it work before since constructor with size_type cppreference

3) Constructs the container with count default-inserted instances of T. No copies are made.

Slava

In this line

std::vector<std::vector<int>> v(n);

you create a vector with 10 elements, which means you can access elements with index [0,9] inclusive. In last data you have 10 8, that would lead to out of range access. If your data is in [1,10] range you need to adjust index:

v[ui-1].push_back(vi);
v[vi-1].push_back(ui);

PS your addition eliminates error because you create std::vector with 10 elements and then you add 10 elements more in the loop, which makes valid index [0,19]. You may fix your code by:

std::vector<std::vector<int>> v(n+1);

without additional loop, if you want to use indexes in [1,10] interval (element with index 0 would still exists there though).

You may consider using std::map<std::vector<int>> and you do not have to worry about indexes:

#include <iostream>
#include <vector>
#include <map>
#include <sstream>

int main()
{
  std::istringstream input( "10 9\n2 1\n3 1\n4 3\n5 2\n6 1\n7 2\n8 6\n9 8\n10 8\n");
  std::cin.rdbuf(input.rdbuf());

  int n,m;
  std::cin >> n >> m;

  std::map<std::vector<int>> v;

  int ui, vi;
  while (m--)
  {
    std::cin >> ui >> vi;
    v[ui].push_back(vi);
    v[vi].push_back(ui);
  }
}

in this case you will only have data with indexes you were used, but access to element by index will be significantly slower. You may also consider std::unordered_map for faster access, if you do not care if data is sorted inside container.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Java

Insert or push_back to end of a std::vector?

From Dev

Implementatnion of std::vector::push_back in MSVC

From Dev

vector::push_back and std::move

From Dev

Implementatnion of std::vector::push_back in MSVC

From Dev

Calling std::vector::push_back() is changing previous elements in vector?

From Dev

Calling std::vector::push_back() is changing previous elements in vector?

From Dev

C++ how to push_back an array int[10] to std::vector<int[10]>?

From Dev

C++ how to push_back an array int[10] to std::vector<int[10]>?

From Dev

no matching function for call to std::vector<std::tuple> push_back

From Dev

Taking the argument by && in std::vector push_back() and std::map operator[]

From Dev

Examples where std::vector::emplace_back is slower than std::vector::push_back?

From Dev

Thread safety std::vector push_back and reserve

From Dev

Cost of std::vector::push_back either succeeding or having no effect?

From Dev

Why std::vector::push_back needs the assignment operator

From Dev

Weird segment fault in function push_back of std::vector

From Dev

std::vector segmentation fault during push_back

From Dev

Thread safety std::vector push_back and reserve

From Dev

std::vector of OpenCV points, no push_back method

From Dev

Why std::vector::push_back segfaults with virtual destructor?

From Dev

how to use std::vector::emplace_back for vector<vector<int> >?

From Dev

how to use std::vector::emplace_back for vector<vector<int> >?

From Dev

Is a std::unique_ptr moved into a std::vector when using push_back?

From Dev

std::string in object being deleted during push_back to std::vector

From Dev

std vector push_back' : 2 overloads have no legal conversion for 'this' pointer error

From Java

std::vector::push_back() doesn't compile on MSVC for an object with deleted move constructor

From Dev

C++ reference changes when push_back new element to std::vector

From Dev

Can C++ std::vector handle push_back from multithreads at the same time?

From Dev

Does std::vector's push_back create a deep copy of the argument?

From Dev

std::vector's push_back() causing a strange compile-time error message

Related Related

  1. 1

    Insert or push_back to end of a std::vector?

  2. 2

    Implementatnion of std::vector::push_back in MSVC

  3. 3

    vector::push_back and std::move

  4. 4

    Implementatnion of std::vector::push_back in MSVC

  5. 5

    Calling std::vector::push_back() is changing previous elements in vector?

  6. 6

    Calling std::vector::push_back() is changing previous elements in vector?

  7. 7

    C++ how to push_back an array int[10] to std::vector<int[10]>?

  8. 8

    C++ how to push_back an array int[10] to std::vector<int[10]>?

  9. 9

    no matching function for call to std::vector<std::tuple> push_back

  10. 10

    Taking the argument by && in std::vector push_back() and std::map operator[]

  11. 11

    Examples where std::vector::emplace_back is slower than std::vector::push_back?

  12. 12

    Thread safety std::vector push_back and reserve

  13. 13

    Cost of std::vector::push_back either succeeding or having no effect?

  14. 14

    Why std::vector::push_back needs the assignment operator

  15. 15

    Weird segment fault in function push_back of std::vector

  16. 16

    std::vector segmentation fault during push_back

  17. 17

    Thread safety std::vector push_back and reserve

  18. 18

    std::vector of OpenCV points, no push_back method

  19. 19

    Why std::vector::push_back segfaults with virtual destructor?

  20. 20

    how to use std::vector::emplace_back for vector<vector<int> >?

  21. 21

    how to use std::vector::emplace_back for vector<vector<int> >?

  22. 22

    Is a std::unique_ptr moved into a std::vector when using push_back?

  23. 23

    std::string in object being deleted during push_back to std::vector

  24. 24

    std vector push_back' : 2 overloads have no legal conversion for 'this' pointer error

  25. 25

    std::vector::push_back() doesn't compile on MSVC for an object with deleted move constructor

  26. 26

    C++ reference changes when push_back new element to std::vector

  27. 27

    Can C++ std::vector handle push_back from multithreads at the same time?

  28. 28

    Does std::vector's push_back create a deep copy of the argument?

  29. 29

    std::vector's push_back() causing a strange compile-time error message

HotTag

Archive