2D Vector using std::vector

Hi,

I am trying to make a 5x3 2D-vector of integers, then set its i-capacity to be 5 and j-capacity to be 3, i.e:

vec2D[i][j] i = 1,2,3,4,5 j = 1,2,3

and then assign integer values to it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <vector>
#include <iostream>

using namespace std;

int main ()
{
  vector<vector<int> > vec2D;

  cout << "i-capacity before reserve: " << vec2D.capacity() << endl;
  vec2D.reserve(5);
  cout << "i-capacity after reserve: " << vec2D.capacity() << endl << endl;

  for (int i=0; i<5; i++) {
      cout << "i = " << i << endl;
      cout << "j-capacity before reserve: " << vec2D[i].capacity() << endl;
      vec2D[i].reserve(3);
      cout << "j-capacity after reserve: " << vec2D[i].capacity() << endl;
      for (int j=0; j<3; j++) {
          vec2D[i][j] = i*5 + j;
      }
  }

  return 0;
}


It compiles, but does not work properly:

Test.exe exited with code -1073741819

i-capacity before reserve: 0
i-capacity after reserve: 5

i = 0
j-capacity before reserve: 336043326
j-capacity after reserve: 336043326
i = 1
j-capacity before reserve: 4282929217
j-capacity after reserve: 4282929217
Press <RETURN> to close this window...


I would appreciate any insight in debugging this code. I am trying to convert a C code with dynamic 2D arrays, to a C++ code. I prefer to keep the vec2D[i][j] = ... way of assignment instead of using vec2D.push_back(...).
Last edited on
Line 19 should probably be j < 3.
http://ideone.com/hLHOhR
Last edited on
Thanks. Sorry, I was quickly making a simple code to show my problem. But actually, the main problem is still there. I edited the code above. The output did not change.
Here is another code to compare the efficiency of various ways to create 2D arrays dynamically.

Assume that we are reading data from an input ASCII file, that at the header line reports the number of rows (or outer_vector_size, or i-range) and at the beginning of each row reports the number of columns (or inner_vector_size, or j-range).

The 4 methods to be compared are:
1) a 2D dynamic array.
2) a vector<vector<int> >, that is resized before assigning the elements.
3) a vector<vector<int> >, without setting the size and just using push_back.
4) a vector<vector<int> >, that its capacity is set using reserve() before assigning the elements

Only the first two methods work so far.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
#include <vector>
#include "timer.h"

using namespace std;

int main()
{
    int outer_sz = 10000; // i-range
    int inner_sz = 5000;  // j-range

////////////////////////////////////////////////////////////

    Timer timer;
    timer.start();

    cout << "1) a 2D dynamic array of size " << outer_sz << " x " << inner_sz << endl;
    int** array2D;
    array2D = new int*[outer_sz];
    for (int i = 0; i < outer_sz; i++) {
        array2D[i] = new int[inner_sz];
        for (int j = 0; j < inner_sz; j++) {
            array2D[i][j] = 1;
        }
    }

    long elapsedMS = timer.stop();
    cout << "Took " << elapsedMS << " ms." << endl;

    for (int i = 0; i < outer_sz; i++)
        delete[] array2D[i];
    delete[] array2D;

////////////////////////////////////////////////////////////

    timer.start();

    cout << "2) a 2D vector of size " << outer_sz << " x " << inner_sz << ", using resize" << endl;
    vector<vector<int> > vec2D;
    vec2D.resize(outer_sz);
    for (int i = 0; i < outer_sz; i++) {
        vec2D[i].resize(inner_sz);
        for (int j = 0; j < inner_sz; j++) {
            vec2D[i][j] = 1;
        }
    }

    elapsedMS = timer.stop();
    cout << "Took " << elapsedMS << " ms." << endl;


////////////////////////////////////////////////////////////

    timer.start();

    cout << "3) a 2D vector of size " << outer_sz << " x " << inner_sz << ", using push_back" << endl;
    vector<vector<int> > vec2D_2;
    vec2D_2.push_back(vector<int> ());
    for (int i = 0; i < outer_sz; i++) {
        for (int j = 0; j < inner_sz; j++) {
            vec2D_2[i].push_back(1);
        }
    }

    elapsedMS = timer.stop();
    cout << "Took " << elapsedMS << " ms." << endl;

////////////////////////////////////////////////////////////

    timer.start();

    cout << "4) a 2D vector of size " << outer_sz << " x " << inner_sz << ", using reserve" << endl;
    vector<vector<int> > vec2D_3;
    vec2D_3.reserve(outer_sz);
    for (int i = 0; i < outer_sz; i++) {
        vec2D_3[i].reserve(inner_sz);
        for (int j = 0; j < inner_sz; j++) {
            vec2D_3[i][j] = 1;
        }
    }

    elapsedMS = timer.stop();
    cout << "Took " << elapsedMS << " ms." << endl;

////////////////////////////////////////////////////////////
    return 0;
}


and here is the output:

(it crashes in the middle:
2D_Vector.exe exited with code -1073741819)

1) a 2D dynamic array of size 10000 x 5000
Took 267 ms.
2) a 2D vector of size 10000 x 5000, using resize
Took 627 ms.
3) a 2D vector of size 10000 x 5000, using push_back

I wouldn't advise a vector of vectors.

http://www.cplusplus.com/articles/G8hv0pDG/
Austin I think he is doing it for an assignment

1
2
3
4
5
he 4 methods to be compared are:
1) a 2D dynamic array.
2) a vector<vector<int> >, that is resized before assigning the elements.
3) a vector<vector<int> >, without setting the size and just using push_back.
4) a vector<vector<int> >, that its capacity is set using reserve() before assigning the elements


or even for experimentation.

*edit also:

1
2
3
    vector<vector<int> > vec2D_2;
    vec2D_2.push_back(vector<int> ());
    for (int i = 0; i < outer_sz; i++) {
shouldn't that be
---
1
2
3
    vector<vector<int> > vec2D_2;
    for (int i = 0; i < outer_sz; i++) {
        vec2D_2.push_back(vector<int> ());

Last edited on
@ naraku9333

Thanks again, I just saw your link:
http://ideone.com/hLHOhR

Interesting! So, my compiler is behaving differently. I am using Qt Creator.
@ Austin J,

Thanks for the useful link :)
Line 74 reserves capacity in the vector. It does not place any objects in the vector, so line 76 attempts to access an element with an invalid index (because there are no elements in the vector.)

Modified not to use your proprietary timer and not to invoke undefined behavior:
http://ideone.com/Njdcz0

Also removed the "reserve" test since resize is just a reserve followed by the addition of default constructed elements, and added the only case that is equivalent to the first.
Last edited on
Topic archived. No new replies allowed.