Debug Assertion Failed: Expression vector subscript out of range - c++

I dont understand why it says subscript out of range when I have reserved the space in the vector. I have created a short form of my code to explain what the problem is better:
#include <vector>
#include <string>
#include <thread>
#include <iostream>
using namespace std;
class A {
public:
vector<vector<string>> foo;
thread* aThread;
A() {
foo.reserve(10); //makes sure we have space...
aThread = new thread([this]() {
for (int i = 0; i < 10; i++) {
foo[i].push_back("Hello"); // Debug assertion failed. :(
}
});
}
};
int main()
{
A a;
a.aThread->join();
for (int i = 0; i < 10; i++) {
for (int j = 0; j < a.foo.size(); j++) {
cout << a.foo[i][j] << " ";
}
cout << endl;
}
return 0;
}
Here it gives the error as soon as I am trying to add the element into my foo vector inside the thread. I cannot figure out what is wrong. Please help.

foo.reserve(10)
Reserves space for elements in foo, but it does not populate any of the elements with an empty std::vector.
You can change it to:
foo.resize(10);
Which will reserve the space and create the empty vector< string > elements, so that you can access them.

Related

How to dynamically allocate data struct array with nullptr and struct members?

I am newly to programming with c++ and I am trying to allocate memory for array of struct. The problem is I don't know the size of elements inside it at compile time. I want the "empty" part to be allocated with null pointers. I run this code below, but there is no the output I expected to be. Could somebody help me?
#include <iostream>
using namespace std;
typedef struct ones{
int a;
int b;
}ones;
ones** twoes = nullptr;
int main()
{
cout<<"Hello World";
for(int i = 0; i < 5; i++)
{
twoes[i]= nullptr;
}
cout<< "i dont get HERE" << endl;
for(int i = 0; i < 5; i++)
{
twoes[i]= new ones;
twoes[i]->a = 2;
cout<< twoes[i]->a <<endl;
}
return 0;
}

Access vector of vector pointers

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

c++ vector one dimensional and two dimensional arrays value assignment

I am confused about c++ two dimensioanal vectors
#include <vector>
int main()
{
//First Code
std::vector<int> oneDimArray;
oneDimArray.push_back(5);
for (int i = 0; i < oneDimArray.size(); i++)
{
std::cout << oneDimArray[i];
}
//Second Code
std::vector<std::vector<int>> twoDimArray;
twoDimArray[0].push_back(5); //Here giving error
for (int i = 0; i < twoDimArray.size(); i++)
{
for (int j : twoDimArray[i])
{
std::cout << j;
}
}
return 0;
}
when i try to run this code First Code is working. But in Second Code i am getting vector out of range error while trying to push back. I guess at first i should say twoDimArray's first size to it. But i dont know how. Because i am definig this twoDimArray in my .h file so if i do this i must do it there. Please can you help me?
The reason this is happening is because of two reasons.
The vector you are trying to access is empty
You are trying to put an int into a vector that was supposed to hold vector<int>s.
Fixed code:
#include <vector>
#include <iostream>
int main()
{
std::vector<int> oneDimArray;
oneDimArray.push_back(5);
for (int i = 0; i < oneDimArray.size(); i++)
{
std::cout << oneDimArray[i];
}
std::vector<std::vector<int>> twoDimArray;
twoDimArray.push_back(oneDimArray); //You can put a vector of ints in here
for (int i = 0; i < twoDimArray.size(); i++)
{
for (int j : twoDimArray[i])
{
std::cout << j;
}
}
return 0;
}
twoDimArray[0].push_back(5) is invalid because the vector had no size yet. After you have pushed back something, or done twoDimArray.resize(new size here);, then you can do that (as long as it isn't out of range).
Also, once a vector has size, you can access the elements of the vector inside the vector by going like twoDimArray[0][0] = 1;. That would give the first value of the first vector inside of the vector to get the value 1.

Fill 2D vector in C++

I'm trying to fill 2D vector in C++ with characters, but when I run this code it ends with one line characters (*..).
How can I fill 2D vector like this:
*.*
.**
#include <iostream>
#include <vector>
int main()
{
std::vector<std::vector<char> > vec2D;
std::vector<char> rowV;
unsigned int row=2;
unsigned int col=3;
char c;
unsigned int temp=0;
while(temp!=col)
{
while(rowV.size()!=row)
{
std::cin>>c;
rowV.push_back(c);
}
vec2D.push_back(rowV);
++temp;
}
return 0;
}
You should clear rowV after each insertion, otherwise it will be full and no other characters will be added. Also, row should be swapped by col and vice-versa, otherwise you will get a 3x2 (and not 2x3) 2D vector.
while(temp!=row)
{
while(rowV.size()!=col)
{
std::cin>>c;
rowV.push_back(c);
}
vec2D.push_back(rowV);
rowV.clear(); // clear after inserting
++temp;
}
It helps to know what [pushing back a 2DVector with an empty 1D vector] looks like.
See the example below.
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
//-v-----A FUNCTION TO PRINT 2D VECTORS
template<typename T> //We don't know what type the elements are yet, so we use a template
void printVec2D(vector<vector<T>> a) // a is the name of our input 2Dvector of type (T)
{
for (int i = 0; i < a.size(); i++) {// a.size() will equal the number of rows (i suppose rows/columns can depend on how you look at it)
for (int j = 0; j < a[i].size(); j++) {// a[i].size() is the size of the i'th row (which equals the number of columns, foro a square array)
std::cout << a[i][j] << "\t";
}
std::cout << "\n";
}
return;
}
//-^--------
int main()
{
int X = 3; int Y = 3;
int VectorAsArray[3][3] = {{1,2,3},
{14,15,16},
{107,108,109}};
vector<vector<int>> T;
for (int i = 0; i < X; i++)
{
T.push_back({});// We insert a blank row until there are X rows
for (int j = 0; j < Y; j++)
{
T[i].push_back(VectorAsArray[i][j]); //Within the j'th row, we insert the element corresponding to the i'th column
}
}
printVec2D(T);
//system("pause"); //<- I know that this command works on Windows, but unsure otherwise( it is just a way to pause the program)
return 0;
}

selection sort array run time error

This is my first time here. I really hope anyone can help me out there. So this is my problem. I keep getting run time error #2 something about a corrupt "arr". But the program runs fine until the end. I can't figure it out.
This is my code:
#include <iostream>
using namespace std;
void main(){
int arr1[3];
int temp;
//INPUT NUMBERS
for (int i=0; i<5;i++)
{
cin>>arr1[i];
}
cout<<endl;
//SORT
for(int c=0;c<5;c++)
{
for (int k=0;k<5;k++)
{
if(arr1[c]<arr1[k])
{
temp=arr1[k];
arr1[k]=arr1[c];
arr1[c]=temp;
}
}
}
for (int m=0; m<5; m++)
{
cout<<arr1[m]<<endl;
}
}
Try this out:
#include <iostream>
using namespace std;
int main()
{
int arr1[5];
int temp;
//INPUT NUMBERS
for (int i = 0; i < 5; i++) {
cin >> arr1[i];
}
cout << endl;
//SORT
for (int c = 0; c < 5; c++) {
for (int k = 0; k < 5; k++) {
if (arr1[c] < arr1[k]) {
temp = arr1[k];
arr1[k] = arr1[c];
arr1[c] = temp;
}
}
}
for (int m = 0; m < 5; m++) {
cout << arr1[m] << endl;
}
}
It compiles properly without any errors. The mistake you had made is in declaring the size of the array. If you want to store 5 in puts, you need to declare an array of size 5. Your code might work, but a good compiler will always give out an error.
The reason being that when you declare an array, you actually create a pointer to the first element of the array. And then, some memory regions are kept for this array, depending on the size. If you try to access an element that is outside these memory regions, you may encounter a garbage value.
Here's your code in ideone.