I wanted to create a matrix with vectors. In the below code, I created a vector with each entry containing a pointer to another vector(myvector) that acts as columns. I push random values to the myvector (i.e. columns). But when I try to access the values of arrays, it pops an compile error saying "error: no match for 'operator*' (operand type is 'std::vector<int>')
at the cout statement. I wonder how do I access the values. I'm pretty sure this is a naive question.
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
std::vector<vector<int>*> main;
for(int j=0; j<3; j ){
vector<int> *myvector = new vector<int>;
main.push_back(myvector);
}
main[0]->push_back(1);
main[0]->push_back(4);
main[1]->push_back(6);
main[1]->push_back(7);
main[1]->push_back(8);
main[2]->push_back(3);
for(int j=0; j<3; j ){
for(uint32_t i=0; i<main[j]->size(); i )
std::cout<<main[j][i]<<" ";
cout<<"\n";
}
return 0;
}
CodePudding user response:
You could just have done
vector<vector<int>> main;
each index of vector main
represents another vector
so to push a number in the first column you can do
main[0].push_back = (_number_)
- To access a number in first row in first column we can do
main[0][0]
CodePudding user response:
This example shows both the syntax you where looking for, and also an example of how you should use std::vector without new/delete.
#include <iostream>
#include <vector>
#include <memory>
// using namespace std; <== teach yourself NOT to do this.
// https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice
void access_pointers_in_2d_vector()
{
std::vector<std::vector<int>*> values; // don't call your variables main!
for (int j = 0; j < 3; j )
{
std::vector<int>* myvector = new std::vector<int>;
values.push_back(myvector);
}
values[0]->push_back(1);
values[0]->push_back(4);
values[1]->push_back(6);
values[1]->push_back(7);
values[1]->push_back(8);
values[2]->push_back(3);
for (int j = 0; j < 3; j )
{
for (uint32_t i = 0; i < values[j]->size(); i )
{
//==================================================================
// this is the syntax you're looking for
// first dereference the pointer then use operator[]
std::cout << (*values[j])[i] << " ";
//==================================================================
}
std::cout << "\n";
}
// don't forget to cleanup your memory!
// if you typed new somewhere then there should
// ALWAYS be a matching delete in your code too!
for (int j = 0; j < 3; j )
{
delete values[j]; // <<==== !!!!!!!
}
}
// for dynamic memory managment new/delete aren't recommended anymore.
// use std::unique_pointer (or if your design really requires it std::shared_ptr)
void using_unique_pointer()
{
// If you really need pointers, use std::unique_ptr
// it will prevent you from introducing memory leaks
const std::uint32_t size = 3ul;
std::vector<std::unique_ptr<std::vector<int>>> values(size);
for (auto& p : values)
{
p = std::make_unique<std::vector<int>>();
}
values[0]->push_back(1);
values[0]->push_back(4);
values[1]->push_back(6);
values[1]->push_back(7);
values[1]->push_back(8);
values[2]->push_back(3);
// output loop is same as for normal pointers.
// no need to call delete, std::unique_ptr will do that for you
}
void without_pointers()
{
// However your whole code in idiomatic c should look like this.
// https://en.cppreference.com/w/cpp/container/vector/vector constructor (10)
// https://en.cppreference.com/w/cpp/language/range-for these loops avoid bugs related to
// letting indices go out of bounds.
std::cout << "\nusing (nested) initializer list and range based for loops : \n";
std::vector<std::vector<int>> rows{ {1,4}, {6,7,8}, {3} };
for (const auto& row : rows)
{
for (const auto& value : row)
{
std::cout << value << " ";
}
std::cout << "\n";
}
}
int main()
{
access_pointers_in_2d_vector();
using_unique_pointer();
without_pointers();
return 0;
}