Heap Corruption Detected in C++ - c++

I keep getting the error Heap Corruption Detected. I have read through several questions on here, but I can't quite find out what is causing this in my code. I am trying to create a 2d array that will hold a matrix that is read from a text file.
// Create a 2d matrix to hold the matrix (i = rows, j = columns)
matrix = new int*[cols];
for(int i = 0; i <= cols; i++) {
matrix[i] = new int[rows];
}
// Populate the matrix from the text file
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
inputFile >> matrix[i][j];
}
}
My destructor is:
for(int i = 0; i <= cols; i++) {
delete[] matrix[i];
}
delete[] matrix;
I've tried debugging, but that does do much help in this case. Any suggestions?

matrix = new int*[cols];
for(int i = 0; i <= cols; i++) {
matrix[i] = new int[rows];
}
For an array with cols elements, the index is from 0 to cols - 1 inclusively.
The heap corruption will be detected when
delete [] matrix;
Since matrix[cols] write a position out of array bound.
UPDATE
As #DanielKO (thank you buddy :p) pointed out in the comment
there is a mismatch, the "Populate the matrix..." loop makes "i"
iterate over "rows" when it should be iterating over "cols".

for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
inputFile >> matrix[i][j];
When you allocated you went from 0 to cols in i. Now you're changing i to be rows.
EDIT: Below would honor your commented row/column rules and follow RAII:
std::vector<std::vector<int>> matrix(rows, std::vector<int>(cols));
for( int i=0; i<rows; ++i ) {
for( int j=0; j<cols; ++j ) {
inputFile >> matrix[i][j];
}
}
// no need for delete matrix cleaned up when leaving scope.

Related

Copying values of 2D array into another

I have a 2D array that I want to assign the values of another array. I'm making a game of life simulator and have everything else working but this. My code is this:
for(int i = 0; i < ROWS; i++) {
for (int j = 0; i < COLS; j++) {
current[i][j] = next[i][j];
}
}
current and next are both bool's. I keep getting the error code EXC_BAD_ACCESS in X-Code. I'm unsure what I'm doing wrong
To re-iterate my comment, the innerloop compares i with COL rather than j. So
for(int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
current[i][j] = next[i][j];
}
}
should solve the issue

using delete is crashing my program

When I try to delete my pointers on distractor, my program is crashing, why?
I don't understand what I am doing wrong in my code.
Am I using new wrong?
class Matrix:
class Matrix
{
private:
double **_array;
int _rows, _cols;
...
Matrix::Matrix(int rows, int cols)
{
if (rows <= 0 || cols <= 0)
exit(-1);
this->_array = new double*[rows];
for (int i = 0; i < rows; i++)
this->_array[i] = new double[cols];
this->_rows = rows;
this->_cols = cols;
}
The problem is here:
void Matrix::pow(int power, Matrix& result)
{
/*if (result == NULL)
exit(-1);*/
if (result._cols != this->_cols || result._rows != this->_rows)
exit(-1);
// Can't pow the matrix, return mat of '0' values
if (this->_cols != this->_rows)
{
for (int i = 0; i < result._rows; i++)
for (int j = 0; j < result._cols; j++)
result.setElement(i, j, 0);
return;
}
/*if (power == 0)
result = 1;*/
double sum = 0;
Matrix temp(this->_rows, this->_cols);
// Copy this matrix to result matrix
for (int i = 0; i < this->_rows; i++)
for (int j = 0; j < this->_cols; j++)
result.setElement(i, j, this->_array[i][j]);
// Pow loop
for (int p = 1; p < power; p++)
{
for (int i = 0; i < this->_rows; i++)
for (int j = 0; j < this->_cols; j++)
{
for (int k = 0; k < this->_rows; k++)
sum += this->getElement(i, k) * result.getElement(k, j);
temp.setElement(i ,j ,sum);
sum = 0;
}
// Copy temp array to result array
for (int i = 0; i < this->_rows; i++)
for (int j = 0; j < this->_cols; j++)
result.setElement(i, j, temp.getElement(i, j));
for (int i = temp._rows; i >= 0; i--)
delete[] temp._array[i];
delete[] temp._array;
}
}
Main:
void main()
{
int rows = 3, cols = 3;
Matrix m1(rows, cols);
Matrix other(rows, cols);
Matrix result(rows, cols);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
{
m1.setElement(i, j, i + j);
other.setElement(i, j, 3 * (i + j + 1));
}
m1.pow(3, result);
}
SetElements:
void Matrix::setElement(int i, int j, double data)
{
if (i < 0 || j < 0)
exit(-1);
if (i >= this->_rows || j >= this->_cols)
exit(-1);
_array[i][j] = data;
}
thanks
1) The word for member function that prepares an object to no longer exist is destructor, not distractor.
2) If you the array form of operator new, using the non-array form of operator delete - which you are - gives undefined behaviour. Use the array form of operator delete instead.
3) Your code, as shown, uses other functions that you have no provided. Any of those, if implemented incorrectly, could be doing an invalid operation on a pointer, and therefore be OTHER causes of your crash.
4) Don't bother to use dynamic memory allocation (operator new, etc) to work with dynamically allocated arrays. You have demonstrated that doing so is error prone. If you want a dynamically allocated array of double use a std::vector<double>. If you want a two dimensional array of double, use a std::vector<std::vector<double> >. Apart from being less error prone, a std::vector releases its memory correctly (as long as you don't write some other code which trashes memory).
In your Matrix, you allocate new arrays:
...
this->_array = new double*[rows]; // <== array of pointers
for (int i = 0; i < rows; i++)
this->_array[i] = new double[cols]; // <== arrays of doubles
...
But in your destructor you delete elements. You have to correct this: Everytime you alocate an array (new []), you have to delete the array (delete []), or you'll get undefined behaviour (for example crash):
for (int i = 0; i < _rows; i++)
delete[] _array[i]; // <== delete array, not element!!
delete[] _array; // <== delete array, not element!!
Note: that everytime you're tempted to use new/delete, you should ask yourself, if it wouldn't be worth to consider using vectors instead. It's very easy as this online demo show with your code reworked
Edit: your problem with pow():
Here you create the matrix object temp:
Matrix temp(this->_rows, this->_cols);
This object will be destructed automatically at the end of the function pow(). THis means that its destructor will call all the necessary delete[].
The problem is that at the end of the function, you manually do the job of the destructor, so you delete[] temp's arrays. Then the destructor tries to delete already deleted objects. This is undefined behaviour and hence the crash !
All you have to do is get rid of the 3 last lines of pow() and the unnecessary delete[] they contain.

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

Setting multidimentional arrays as vector in C++

I have "int array[10][10]" (Two dimentional (Size can be changed!) )
and I want to set all of items into "vector> Vector"
I tried:
vector<vector<int>> Vector;
for(int i = 0; i < 10; i++)
for(int j = 0; j < 10; j++)
{
Vector[i][j] = array[i][j];
}
But it doesnt work. I get this exception:
The program has unexpectedly finished.
vector<vector<int>> Vector(10, vector<int>(10));
will do the trick

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