Need help with a vector of vectors

Hi all,

I am trying to work with a vector of vectors... just trying to do basic operations with it. Eventually, I'm going to use a vector of vectors to code a Radix sorting algorithm, and I wanted the vector of vectors to act as the bin. When I started coding it, I realized I don't understand vectors as well as I thought.

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

using namespace std;


int main()
{
	vector< vector<int> > buff(10);

	for(int i=0; i<10; i++){
		int y = rand()%10; //gen random num to test operability
		buff[y][0].push_back(1);
	}

	for(int i=0; i<10; i++)
		for(int p=0; p<10; p++)
		cout << buff[i][p] << " ";


return 0;
}


This is what I have so far. When I compile this code, I incur the compilers wrath. I have tried other variations of this code, and its wrath never abates.

Could anyone give me some guidance on how to get this working properly? I need to be able to add ints to any of the rows 1-9.
Last edited on
just remove the [0] when you push_back. You would do that kind of push_back if you have a vector<vector<vector<int> > >.
Hi Destroyer,

When I do change from:

buff[y][0].push_back(1);

To:

buff[y].push_back(1);

I get a Debug Assertion Failed

Vector subscript out of range
This is because you're running the second loop over 10x10 elements while you're not really filling them all with your push_back.

In the first step of your program, you initialise 10 empty vectors, and then you push_back 10 elements randomly to those vectors. Think about it! how are you asking your program to give you 100 elements while you have only 10 elements defined?

You have 2 options here, you either initialise your vector to have 100 elements and then use operator[] to fill them rather than push_back:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
vector< vector<int> > buff(10,vector<int>(10)); //initialise all vectors with 10 elements each

	for(int i=0; i<10; i++){
		int y = rand()%10; //gen random num to test operability
                for(j = 0; j < 10; j++)
                {
                     if(buff[y][j] == 0) //assign the value if the value is 0, so you're simulating a push_back
                     {
                          buff[y][j] = 1;
                          break;
                     }
                }
	}


or you check in the output whether the size is within range:

1
2
3
for(int i=0; i<10; i++)
		for(int p=0; p<buff[i].size(); p++)
		cout << buff[i][p] << " ";


This would work, hopefully :)
Last edited on
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
#include <iostream>
#include <vector>
using namespace std;  

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

	// To set values
	for(int i = 0; i < 10; i++)
	{
		vector<int> temp; // create an array, don't work directly on buff yet.
		for(int j = 0; j < 10; j++)
			temp.push_back(i); 
 
		buff.push_back(temp); // Store the array in the buffer
	}

	//To access values
	for(vector<vector<int> >::iterator it = buff.begin(); it != buff.end(); ++it)
	{
		//it is now a pointer to a vector<int>
		for(vector<int>::iterator jt = it->begin(); jt != it->end(); ++jt)
		{
			// jt is now a pointer to an integer.
			cout << *jt;
		}
		cout << endl;
	}

	return 0;
}
0000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999
Press any key to continue . . .
Last edited on
Another thing that can be done to avoid confusion is to typedef:
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
#include <iostream>
#include <vector>
using namespace std;  

typedef vector<int> intvec;

int main()
{
    vector<intvec> buff;

    for(int i = 0; i < 10; i++)
    {
        intvec temp; // create an array, don't work directly on buff yet.
        for(int j = 0; j < 10; j++)
            temp.push_back(i); 
 
        buff.push_back(temp); // Store the array in the buffer
    }

    for(vector<intvec>::iterator it = buff.begin(); it != buff.end(); ++it)
    {
        //it is now a pointer to a intvec
        for(intvec::iterator jt = it->begin(); jt != it->end(); ++jt)
        {
            // jt is now a pointer to an integer.
            cout << *jt;
        }
        cout << endl;
    }

    return 0;
}
Finally here's something that doesn't use iterators to access, It may be more familiar to you. From what I understand, it isn't as safe to use in some situations.

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
#include <iostream>
#include <vector>
using namespace std;  

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

    for(int i = 0; i < 10; i++)
    {
        vector<int> temp; // create an array, don't work directly on buff yet.
        for(int j = 0; j < 10; j++)
            temp.push_back(i); 
 
        buff.push_back(temp); // Store the array in the buffer
    }

    for(int i = 0; i < buff.size(); ++i)
    {
        for(int j = 0; j < buff[i].size(); ++j)
            cout << buff[i][j];
        cout << endl;
    }

    return 0;
}
0000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999
Press any key to continue . . .
Last edited on
Regarding your problem, you randomly pushback 1 into the buffers, but then you try and access 10 elements of the inner vector (which may not exist).

To do this safely I've modified your code as little as possible:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <cstdlib>
#include <vector>

using namespace std;


int main()
{
	vector< vector<int> > buff(10);

	for(int i=0; i<10; i++){
		int y = rand()%10;
		buff[y].push_back(1); // Fixes the compiler error
	}

	for(int i=0; i<buff.size(); i++) // Ensure that you don't access any elements that don't exist
		for(int p=0; p<buff[i].size(); p++) // You may not have had 10 in here before, only go to size().
		cout << buff[i][p] << " ";


return 0;
}

Thanks Destroyer and Stewbond for the life raft ! That one had me totally stumped.

Topic archived. No new replies allowed.