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;
}