c++ vector allocation error segmentation fault - c++

i'm trying to use a matrix of vectors declared like this :
vector<vector<Neurone*>* > Neurones;
I have already created a class Neurones by the way.
this is the code :
NeuralNetwork::NeuralNetwork(vector<int> NeuroneNumbers, vector<vector<vector<double>* >* > lw)
{
for (int i = 0; i < NeuroneNumbers.size(); i++)
{
if (i == 0)
{
Neurones.push_back(new vector<Neurone*>());
for (int j = 0; j < NeuroneNumbers[i]; j++)
{
Neurones[i]->push_back(new Neurone(new Neurone[0], new double[0]));
if (j == NeuroneNumbers[i] - 1)
{
(*Neurones[i])[j]->Value = 1;//Here is the error ! with i=0 j=0 segmentation fault !
}
}
}}

A matrix of std::vector is actually a std::vector of std::vector.
Here is an example:
#include <iostream>
#include <vector>
int main() {
// this is actually a 2D "array"
std::vector< std::vector<int> > v;
int N = 5; // rows
int M = 5; // columns
v.resize(N); // create N rows
for(int i = 0 ; i < N ; ++i)
for(int j = 0 ; j < M ; ++j)
v[i].push_back(j); // fill the matrix
//print
for(int i = 0 ; i < N ; ++i)
for(int j = 0 ; j < M ; ++j)
std::cout << v[i][j] << "\n";
return 0;
}
[EDIT]
I believe, that you do need to use pointers for your purpose.

Neurones[i]->push_back(new Neurone(new Neurone[0], new double[0]));
Why are you doing this? What does new Neurone[0] means? If you meant to create a Neurone by this statement, then actually you are passing one Neurone object to the constructor of another.
Neurones[i])[j] will give you a pointer to Neuron. So if Neuron class has a public member variable named Value, you can set it by
Neurones[i])[j]->Value = 1; // no need the * operator
However, you are using pointers unnecessarily, and the usage is error prone. Your code can be greatly simplified:
vector<vector<Neurone*> > Neurones;
NeuralNetwork::NeuralNetwork(vector<int> NeuroneNumbers, vector<vector<vector<double>* >* > lw)
{
for (int i = 0; i < NeuroneNumbers.size(); i++)
{
if (i == 0)
{
vector<Neurone*> neuronVector;
for (int j = 0; j < NeuroneNumbers[i]; j++)
{
Neurone neuron=new Neurone(/*constructor params*/); // create a Neuron object
if (j == NeuroneNumbers[i] - 1)
{
neuron.Value = 1;
}
neuronVector.push_back(neuron);
}
Neurones.push_back(neuronVector);
}}

Related

I keep getting this error and it is getting me more and more frustrated, please help me out

Line 1034: Char 9: runtime error: reference binding to null pointer of type 'std::vector<int, std::allocator>' (stl_vector.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:1043:9
void gameOfLife(vector<vector<int>>& board) {
vector<vector<int>> newBoard;
for(int i = 0; i < board.size(); i++){
for(int j = 0; j < board[i].size(); j++){
if(board[i][j] == 0 && neibSum(board,i,j) == 3)
newBoard[i][j] = 1;
else if(board[i][j] == 1 && neibSum(board,i,j) > 3)
newBoard[i][j] = 0;
else if(board[i][j] == 1 && neibSum(board,i,j) < 2)
newBoard[i][j] = 0;
else
newBoard[i][j] = 1;
}
}
for(int i = 0; i < board.size(); i++){
for(int j = 0; j < board[i].size(); j++){
cout << newBoard[i][j] << " ";
}
cout << endl;
}
}
Your variable 'newboard' is a vector of size 0.
in:
newBoard[i][j] = 1;
you are trying to access unallocated memory.
You need to allocate the memory first (using, e.g., resize).
vector<vector<int>> newBoard;
newBoard.resize(board.size());
for(int i = 0; i < board.size(); i++){
newBoard[i].resize(board[i].size());
for(int j = 0; j < board[i].size(); j++){
...
edit:
p.s., you can use the .at() function, instead of [] to access vector elements:
newBoard.at(i).at(j)
This contains bounds checking. It won't solve your problem, but it will give you a much easier-to-understand error message.
You can initialize your board in one line
#include <vector>
// two constants for you board size
// stl containers mostly accept std::size_t for their sizes
constexpr std::size_t board_height_v = 25;
constexpr std::size_t board_width_v = 80;
enum class cell
{
dead,
alive
};
int main()
{
// I made a cell enum so you can more easily spot where the initial cell value is set.
// now lets initialize the board to the correct size
std::vector<std::vector<cell>> newBoard(board_height_v, std::vector<cell>(board_width_v,cell::dead));
return 1;
}

Push back data into a 2D vector

I am trying to create a 2d vector of set size and then insert data into it. The issue I am having is being able to insert the data filling up each column and row in the 2d vector.
I have read through various other threads, but cannot find an implementation that works for me.
Here is some sample code for my issue:
int main()
{
vector<string> strVec = { "a","b","c","d" };
// letters to insert into vector
// this is just a sample case
vector< vector<string>> vec; // 2d vector
int cols = 2; // number of columns
int rows = 2; // number of rows
for (int j = 0; j < cols; j++) // inner vec
{
vector<string>temp; // create a temporary vec
for (int o = 0; o < rows; o++) // outer vec
{
temp.push_back("x"); // insert temporary value
}
vec.push_back(temp); // push back temp vec into 2d vec
}
// change each value in the 2d vector to one
// in the vector of strings
// (this doesn't work)
// it only changes the values to the last value of the
// vector of strings
for (auto &v : strVec)
{
for (int i = 0; i < vec.size(); i++)
{
for (int j = 0; j < vec[i].size(); j++)
{
vec[i][j] = v;
}
}
}
// print 2d vec
for (int i = 0; i < vec.size(); i++)
{
for (int j = 0; j < vec[i].size(); j++)
{
cout << vec[i][j];
}
cout << endl;
}
}
You are assigning same string to all elements of vec again and again in the loop for (auto &v : strVec).
That is, vec[0][0]=vec[0][1]=vec[1][0]=vec[1][1]=a, vec[0][0]=vec[0][1]=vec[1][0]=vec[1][1]=b, and so on.
Removing this outer loop and assigning strVec[i*cols+j] to vec[i][j], we can get desired output.
DEMO is here.
for (int i = 0; i < vec.size(); i++)
{
for (int j = 0; j < vec[i].size(); j++)
{
vec[i][j] = strVec[i*cols+j];
}
}
for (int i = 0; i < vec.size(); i++)
{
for (int j = 0; j < 2; j++)
{
cout << vec[i][j];
}
cout << endl;
}

Matrix multiplication using 2d vector

Following is my code:
void matrix(int rowsInA, int columnsInA, int columnsInB){
std::vector< vector<int> > a;
std::vector< vector<int> > b;
for (int i = 0; i < rowsInA; i++) {
vector<int> myRow(1);
a.push_back(myRow);
for (int j = 0; j < columnsInA-1; j++) {
int x = rand() % 100;;
myRow.push_back(x);
}
}
for (int i = 0; i < rowsInA; i++) {
vector<int> myRow(1);
b.push_back(myRow);
for (int j = 0; j < columnsInB-1; j++) {
int x = rand() % 100;;
myRow.push_back(x);
}
}
std::vector< vector<int> > c = multiply(a, b);
for (int i = 0; i < rowsInA; i++) {
for (int j = 0; j < columnsInB; j++) {
cout << c[i][j];
}
}
}
std::vector< vector<int> > multiply(std::vector< vector<int> > a , std::vector< vector<int> > b) {
int rowsInA = 9;
int columnsInA = 9; // same as rows in B
int columnsInB = 9;
std::vector< vector<int> > d;
for (int i = 0; i < rowsInA; i++) {
for (int j = 0; j < columnsInB; j++) {
vector<int> myRow;
myRow.push_back(a[i][0]);
d.push_back(myRow);
for (int k = 0; k < columnsInA; k++) {
myRow.push_back(myRow[i]+ a[i][k] * b[k][j]);//error here
}
}
}
return d;
}
first function matrix() creates two vector within a vector and assigns random values to it and then call multiply in which vectors are multiplied.
It is giving vector subscript out of range error
Your code:
for (int i = 0; i < rowsInA; i++) {
vector<int> myRow(1);
a.push_back(myRow);
for (int j = 0; j < columnsInA-1; j++) {
int x = rand() % 100;;
myRow.push_back(x);
}
}
Constructs a single element vector, pushes it on to a, appends some
values to your temporary, and then throws it away. C++ is not Java or C#. The vector at the back of a is not changed by changes to myRow.
You also seem to be putting a fixed value as the first element of myRow, and
then appending randomness to it. Is that what you meant?
What you need is:
for (int i = 0; i < rowsInA; i++) {
vector<int> myRow;
myRow.reserve(columnsInA);
myRow.push_back(0); // First element fixed.
for (int j = 1; j < columnsInA; j++) {
const int x = rand() % 100;;
myRow.push_back(x);
}
a.push_back(myRow);
}
Alternatively, making all the values random, and working directly with the vector:
a.reserve(rowsInA);
for (int i = 0; i < rowsInA; i++) {
a.push_back( {} );
a.back().reserve(columnsInA);
for (int j = 0; j < columnsInA; j++) {
const int x = rand() % 100;;
a.back().push_back(x);
}
}
You have a similar problem with initializing B, and your multiply loop needs to accumulate a[i][k] * b[k][j] into a temporary sum, then push that onto myRow, and finally push myRow onto d.
Finally, when you have got this working, look up how to write a Matrix class that stores all the data in a vector with rows*cols elements and then uses an indexing function to refer to it. Your cache will thank you.

How do I copy the elements of a 2D array onto a 1D vector?

So i keep trying to transfer the elements but it keeps giving me repeated elements, it fails to properly copy the 2D array onto a 1D vector
// This was one of my attempts
vector<int> rando(int rowsize, int columnsize)
{
int elements = rowsize*columnsize;
vector<int> x(elements);
int matrix[100][100];
for(int i = 0; i < rowsize; i++)
{
for(int j = 0; j < columnsize; j++)
{
srand((int)time(0));
matrix[i][j]= -10 + rand() % 21;
for(int n=0; n < elements; n++)
x[n]=matrix[i][j];
}
// Ive also tried this
for(int n=0; n < elements; n++)
{
for(int i = 0; i < rowsize; i++)
{
for(int j = 0; j < columnsize; j++)
{
x[n]=matrix[i][j];
}
}
}
}
return x;
}
Why do you want to store data into the matrix first and copy it into the vector afterwards? Use the vector from the start.
std::vector<int> rando(std::size_t rowsize, std::size_t columnsize)
{
std::vector<int> v(rowsize*columnsize);
std::mt19937 mt{std::random_device{}()};
std::uniform_int_distribution<int> rand_dist(-10, 10);
for (auto & e : v) e = rand_dist(mt);
return v;
}
If you want to transfer data from a matrix into a vector you must calculate the proper index or just increment a single variable as Thomas Matthews suggests.
constexpr std::size_t n = 100, m = 100;
int matrix[n][m];
// do stuff with matrix
std::vector<int> v(n*m);
for (std::size_t i=0; i<n; ++i)
{
for (std::size_t j=0; j<m; ++j)
{
v[i*m + j] = matrix[i][j];
}
}
THe general copy should loop through the 2 dimensions, and just increment the target index at each iteration (no third nested loop):
int n=0;
for(int i = 0; i < rowsize; i++)
{
for(int j = 0; j < columnsize; j++)
{
...
x[n++]=matrix[i][j]; // not in an additional for loop !!
}
} // end of initialisation of matrix
If your matrix is a 2D array (i.e. contiguous elements) you can also take the following shortcut using <algorithm>:
copy (reinterpret_cast<int*>(matrix), reinterpret_cast<int*>(matrix)+elements, x.begin());
Try this:
unsigned int destination_index = 0;
for(int i = 0; i < rowsize; i++)
{
for(int j = 0; j < columnsize; j++)
{
x[destination_index++]=matrix[i][j];
}
}
The destination index is incremented after each assignment to a new slot.
No need for a 3rd loop.
It is enough to use two loops.
For example
srand((int)time(0));
for(int i = 0; i < rowsize; i++)
{
for(int j = 0; j < columnsize; j++)
{
matrix[i][j]= -10 + rand() % 21;
x[i * columnsize + j] = matrix[i][j];
}
}
In general if you have a two-dimensional array and want to copy nRows and nCols of each row elements in a vector then you can use standard algorithm std::copy declared in header <algorithm>
For example
auto it = x.begin();
for ( int i = 0; i < nRows; i++ )
{
it = std::copy( matrix[i], matrix[i] + nCols, it );
}

Memory issues with two dimensional array

Following this nice example I found, I was trying to create a function that dynamically generates a 2D grid (two dimensional array) of int values.
It works fairly well the first couple of times you change the values but if crashes after that. I guess the part where memory is freed doesn't work as it should.
void testApp::generate2DGrid() {
int i, j = 0;
// Delete previous 2D array
// (happens when previous value for cols and rows is 0)
if((numRowsPrev != 0) && (numColumnsPrev != 0)) {
for (i = 0; i < numRowsPrev; i++) {
delete [ ] Arr2D[i];
}
}
// Create a 2D array
Arr2D = new int * [numColumns];
for (i = 0; i < numColumns; i++) {
Arr2D[i] = new int[numRows];
}
// Assign a random values
for (i=0; i<numRows; i++) {
for (j = 0; j < numColumns; j++) {
Arr2D[i][j] = ofRandom(0, 10);
}
}
// Update previous value with new one
numRowsPrev = numRows;
numColumnsPrev = numColumns;
}
I see 1 major bug:
// Assign a random values
for (i=0; i<numRows; i++){
for (j=0; j<numColumns; j++){
Arr2D[i][j] = ofRandom(0, 10);
}
}
Here the variable 'i' is used as the first index into 'Arr2D' and goes to a max of (numRows -1)
While in this code:
for (i=0; i<numColumns; i++)
{
Arr2D[i] = new int[numRows];
}
The variable 'i' is used as the first index but goes to a max of (numColumns-1). If numRows is much larger than numColumns then we are going to have a problem.
As a side note. When you try and clean up you are leaking the columns:
if((numRowsPrev != 0) && (numColumnsPrev != 0))
{
for (i=0; i<numRowsPrev; i++){
delete [ ] Arr2D[i];
}
// Need to add this line:
delete [] Arr2D;
}
Next thing to note.
This is truly not a good idea. Use some of the provided STL classes (or potentially boost Matrix). This looks like you are binding global variables and all sorts of other nasty stuff.
2-dim array in C++ with no memory issues:
#include <vector>
typedef std::vector<int> Array;
typedef std::vector<Array> TwoDArray;
Usage:
TwoDArray Arr2D;
// Add rows
for (int i = 0; i < numRows; ++i) {
Arr2D.push_back(Array());
}
// Fill in test data
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++) {
Arr2D[i].push_back(ofRandom(0, 10));
}
}
// Make sure the data is there
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++) {
std::cout << Arr2D[i][j] << ' ';
}
std::cout << '\n';
}