Dealocating 2d arrays pointers - c++

What am I doing wrong? I allocated using new but when i try to delete[] it gives me an error.
mycode:
int** ma;
int n;
int m;
m = nr_col_lin;
n = nr_col_lin;
ma = new int*[m];
for(i = 0; i < m; i++)
ma[i] = new int[n];
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
ma[i][j] = 0;
}
}
and the dealocation:
for(int i = 0; i < m; ++i)
delete[] ma[i];
delete [] ma;
EDIT:
I found the problem... it wasn't in the code... I was deleting something I didn't allocate.

There is absolutely nothing wrong in your code. It is perfect. The probem must be somewhere else, assuming nr_col_lin is initialized with some valid value, i.e make sure it is not 0 or negative. If it is size_t or some unsigned integral value, then make sure m and n are greater than 0.

Related

Buffer overrun while writing to 'costMatrix'

I am getting a warning when writing to a dynamically allocated array that I can't seem to figure out. Visual Studio says that there is a "buffer overrun." However, I don't see what would cause that error. For reference, here is my code:
//Initialize the cost matrix
int numMembers = 10;
int** costMatrix = new int* [numMembers];
for (int i = 0; i < numMembers; i++)
{
costMatrix[i] = new int[5];
}
for (int i = 0; i < numMembers; i++)
{
for (int j = 1; j < 3+1; j++)
{
int index = 3;
costMatrix[i][index] = j; //Set cost matrix
}
}
Any help would be greatly appreciated. Thanks!

Why not array deallocate when using assignment operator?

When running the code I keep getting error "free(): double free detected in tcache 2". How can I not deallocate new instance array? Shouldn't it be deallocate at the moment I run the second instance? Why deallocate constructor doesn't work for the n instance? How can I solve this? Should I deallocate the arr of n manually in assignment operator?
#include <iostream>
#include <iomanip>
using namespace std;
class spMatrix{
private:
int N;
public:
double** arr;
spMatrix(): N(0), arr(NULL){};
spMatrix(int size): N(size){
N = size;
arr = new double* [size];
for(int i = 0; i < size; i++) arr[i] = new double [size];
};
//copy constructor
spMatrix(const spMatrix& original){
N = original.N;
arr = new double* [N];
for (int i = 0; i < N; ++i)
{
arr[i] = new double [N];
for (int j = 0; j < N; ++j)
{
arr[i][j] = original.arr[i][j];
}
}
}
~spMatrix(){
if(arr != NULL){
for (int i = 0; i < N; i++)
{
if (arr[i] != NULL) delete [] arr[i];
}
delete [] arr;
}
}
spMatrix& operator = (spMatrix const & other){
N = other.N;
arr = other.arr;
for(int i = 0; i < N; i++) {
arr[i] = other.arr[i];
for (int j = 0; j < N; j++){
arr[i][j] = other.arr[i][j];
}
}
return *this;
}
void show(){
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < N; ++j)
{
cout << arr[i][j] << " ";
}
cout << endl;
}
}
};
int main(int argc, char const *argv[])
{
spMatrix m(2);
spMatrix n(2);
m = n;
m.show();
return 0;
}
In your copy constructor:
N = other.N;
arr = other.arr;
for(int i = 0; i < N; i++) {
arr[i] = other.arr[i];
for (int j = 0; j < N + 1; j++){
arr[i][j] = other.arr[i][j];
}
}
return *this;
}
This only copies/duplicates the 2nd dimension of the 2D-matrix. The first dimension is not duplicated. Try to focus your attention on just the following line:
arr = other.arr;
If you think about this for a moment, it should be clear that you end up with two different objects having the same identical arr class member pointer. This is not correct. Different matrix objects should always be completely independent of each other and not share any pointers in common (at least not without reference-counting, and other complicated semantics).
You simply need to make a copy of arr, too. Everything else remains the same. It should probably be something like:
arr = new double* [N];
Looks like everything else can remain the same, note how this is identical to the same allocation in the regular constructor.
However the assignment operator has the same defect, but after understanding the problem in the copy constructor it should be clear how to fix it (same fix).
Your assignment operator also has a separate bug: it leaks memory. It needs to delete the entire 2D matrix in this, before cloning it from other.
Your problem is in the copy assignment operator:
spMatrix& operator = (spMatrix const & other){
N = other.N; // <<<A>>>
arr = other.arr; // <<<B>>>
for(int i = 0; i < N; i++) {
arr[i] = other.arr[i];
for (int j = 0; j < N + 1; j++){
arr[i][j] = other.arr[i][j];
}
}
return *this;
}
There are two significant and separate problems here. First, the current object owns some memory, an array of N arrays of length N.
However, after line <<>> you no longer know how many arrays you hold.
Second, after line <<>> you no longer know the address of your arrays, and so they are leaked.
Worse, line <<>> is also now pointing this object's array into other's memory, and both objects think they own that array. When one spMatrix destructor runs, the other will still point to it and use deleted memory. When the second one is destroyed, it'll be the second delete on the already deleted memory.
All of the copying you're trying to do in those for loops is not really doing anything, since you're assigning from and to the same address.
You must allocate new buffers before copying them, and not look at the address the other object has... because it's their memory not yours to take.
And you should keep the old pointers around, so that you can delete them after the allocations complete. That way if something fails you can still put it back, without messing your object up first. For example, the logic of line <<>> should be last, not first, only after everything succeeds.
I changed the assignment operator as below and it solved it.
spMatrix& operator = (spMatrix const & other){
N = other.N;
arr = new double* [N];
for(int i = 0; i < N; i++) {
arr[i] = new double[N];
for (int j = 0; j < N; j++){
arr[i][j] = other.arr[i][j];
}
}
return *this;
}

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.

C++ 2D dynamic array allocation

I have a float** array that contains num_rows rows and num_cols columns. I'd like to determine the number of occurrences of every number between 0-9 columnwise. To do this, I thought of using another 2D array of size [10][num_cols], so that for each column the number corresponding to an element is the number of occurrences of that number in the original table.
Example: if the original table contains 1 2 3 1 1 in the fifth column, then in the second column, the values should be like: 1-> 3, 2 -> 1, 3 -> 1.
I tried using the function as follows, but it gives me a pointer error. I tried using vectors but that too brings no luck.
int ** attribute_count(float * * input, int row_num, int col_num) {
int ** arr_2 = new int * [10];
int * arr = new int[10 * col_num];
int counter = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < col_num; j++) {
arr_2[i][j] = 0;
}
}
for (int i = 0; i < 9; i++) {
for (int j = 0; j < col_num; j++) {
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}
EDIT:
I tried your suggestions. The new code is:
int** attribute_count(float** input, int row_num, int col_num) {
int** arr_2 = new int* [10];
int* arr = new int[10 * col_num];
int counter = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < col_num; j++) {
arr_2[i] = new int[col_num];
}
}
for (int i = 0; i < 11; i++) {
for (int j = 0; j < col_num; j++) {
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}
This still gives me memory errors. The function is being called in the .cpp like this:
int** attr = attribute_count(training_data, 10, num_cols_train);
cout<<attr[5][1];
Any idea what I'm doing wrong even now?
I think your problem is in incorrect allocation of the 2D array. Try
int ** arr_2 = new int* [row_num];
for (int i = 0; i < row_num; i++)
arr_2[i] = new int[col_num];
You've only allocated one dimension of arr_2. You need to loop through and allocate an array of ints on each one to get the 2nd dimension.
EDIT: Also, what's up with arr? You allocate it, never use it, don't return it, and don't deallocate it. That's how we spell memory leak.
arr_2 is defined and allocated as an array of pointers to int, but you don't actually assign/allocate those pointers.
Here's a stab at correcting your code - however I'm not convinced you have rows and columns the right way around...
int ** attribute_count(float ** input, int row_num, int col_num)
{
int ** arr_2 = new int * [10];
for (int i = 0; i < 10; i++)
{
arr_2[i] = new int[col_num];
for(int j = 0 ; j < col_num ; j++)
{
arr_2[i][j] = 0;
}
}
for (int i = 0; i < row_num; i++)
{
for (int j = 0; j < col_num; j++)
{
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}

struct with list<..> in 2 dim. dynamic array segfaults on delete

for a little project i wanted to use a struct with an stl container in it.
This thingy is then packet into a dynamic 2 dim. array, but when i try to delete it,
it segfaults.
Here is the code:
struct cell{
list<pair<double, double> > alist;
};
int main()
{
struct cell ** myAr = new cell*[5];
for(int i = 0; i < 5; ++i)
myAr[i] = new cell[5];
for(int j = 0; j < 5; ++j)
delete myAr[j];
delete myAr;
return 0;
}
Can anyone help me with this?
Thanks in advance.
Flo.
Use delete[] for memory allocated with new[]:
for(int j = 0; j < 5; ++j)
delete[] myAr[j];
delete[] myAr;
You allocated with new[] so you need to free with delete[]:
for(int j = 0; j < 5; ++j)
delete [] myAr[j];
delete [] myAr;
int main()
{
struct cell ** myAr = new cell*[5];
for(int i = 0; i < 5; ++i)
myAr[i] = new cell[5];
for(int j = 0; j < 5; ++j)
{
delete[] myAr[j];
myAr[j] = 0;
}
delete[] myAr;
myAr = 0;
return 0;
}
i think delete [] myAr; should work fine

Categories