How to delete this 2D Array in C++ - c++

I've absolutely no idea why my delete codes inside the destructor won't be able to functionally well. I hope u guys can help me for this.
Thank you so much!
class Array2D
{
public:
Array2D();
Array2D(int, int);
~Array2D();
private:
int row;
int col;
int **p;
};
Array2D::Array2D()
{
// Default Constructor
}
Array2D::Array2D(int rows, int cols)
{
this -> row = rows;
this -> col = cols;
p = new int* [row];
for(int i=0; i< row; i++)
p[i] = new int[col];
// Fill the 2D array
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
{
p[i][j] = rand () % 100;
}
}
Array2D::~Array2D()
{
// I'm using this way to delete my 2D array.
// however, it won't work!
for (int i = 0; i < row; i++)
{
delete[]p[i];
}
delete[]p;
}

You are not initializing anything in your default constructor. That means that the destructor will go mad on a default constructed object. You are also not disabling the copy constructor, which is not functioning with your class, because if you have copied an object, it will try to delete the same table twice. Change it as follows, for example
class Array2D
{
public:
Array2D();
Array2D(int, int);
~Array2D();
private:
int row;
int col;
int **p;
void initialize(int rows, int cols);
// disable copy functions (make private so they cannot
// be used from outside).
Array2D(Array2D const&);
Array2D &operator=(Array2D const&);
};
Array2D::Array2D()
{
initialize(0, 0);
}
Array2D::Array2D(int rows, int cols)
{
initialize(rows, cols);
}
void Array2D::initialize(int rows, int cols) {
this -> row = rows;
this -> col = cols;
p = new int* [row];
for(int i=0; i< row; i++)
p[i] = new int[col];
// Fill the 2D array
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
{
p[i][j] = rand () % 100;
}
}

Related

How to create a 2D array using a function?

I am trying to define a 2D array, but I want to do it in a function,
here is my code:
int** createArray( int columns, int rows)
{
int** array[rows];
for(int i = 0; i < rows; i++)
{
array[i] = new int*[columns];
}
for(int i = 0; i <columns; i++)
{
for(int j = 0; j < rows; j++)
{
array[i][j] = 0;
std::cout <<array[i][j];
}
std::cout<<"\n";
}
return *array;
}
int main()
{
int **myArray = createArray(3,5);
for(int k =0; k < 5; k++)
{
if( (myArray[0][k] == 0) && (&myArray[1][k] == 0)) //segmentation fault
{
myArray[2][k] = 10; //segmentation fault
}
delete[] myArray;
}
But it causes errors which can be seen as comments in lines. I am new to C++ and I do not know how to fix this.
Thank you very much
Prefer std::vector over manual memory management:
std::vector<std::vector<int>> createArray(int columns, int rows)
{
return std::vector<std::vector<int>(rows, std::vector<int>(columns));
}
int main()
{
int COLUMNS = 5;
int ROWS = 3;
auto myArray= createArray(COLUMNS, ROWS);
/*
Do stuff
*/
//std::vector handles delete on it's own, no need to clean up
}
If you cannot use std::vector for some reason, this is the a way to initialize 2D array on the heap:
int** createArray(int columns, int rows)
{
int** arr = new int*[rows];
for(int i = 0; i < rows; ++i)
{
arr[i] = new int[columns];
}
return arr;
}
int main()
{
int COLUMNS = 5;
int ROWS = 3;
int** myArray= createArray(COLUMNS, ROWS);
/*
Do stuff
*/
//you need to a delete for every new and delete[] for every new[]
for(int i = 0; i < rows; ++i)
{
delete[] myArray[i];
}
delete[] myArray;
}

I don't understand what's wrong

Here is a my own Matrix class:
class Matrix {
private:
int row; // rows
int col; // columns
double** matrix; // pointer to this matrix
public:
Matrix();
Matrix(int row, int col);//creating matrix based on two params
Matrix(double** matx, int row, int col); //Here is a problem
Matrix(Matrix& N);//copy constructor
~Matrix();
//first, second and fourth constructors works good
int getRow();
int getCol();
void changeSize(int row, int col);
void randValues();
void writeValues();
};
Here is a body of constructor, This constructor need take a exists matrix as parameter and create a new one based on the matrix provided (it's NOT a copy constructor)
Matrix::Matrix(double** matx, int row, int col){
//allocated memory for new matrix
matrix = new double*[row];
for (int i = 0; i < row; i++){
matrix[i] = new double[col];
}
// //copy values to new matrix
for(int i=0; i<row; i++)
{
for(int k = 0; k < col; k++)
{
matrix[i][k] = matx[i][k];
}
}
};
int main(){
double** test = new double *[5];
for(int i = 0; i < 5; i++){
test[i] = new double;
}
for(int i = 0; i < 5; i++){
for(int k = 0; k < 5; k++){
test[i][k] = 0.11;
cout << test[i][k] << " ";//just for make me sure if is ok
}
cout << "\n";
}
Matrix *matx = new Matrix(test,5,5);
matx->writeValues();
return 0;
}
And when I run a program they write on console lots of zeros values and few garbage and of the end is: Process returned -1073741819 (0xC0000005) execution time : 2.162 s

Creating random matrix in constructor

So, i'm making program that will multiply and adds matrices. I created class matrix with constructor:
class Matrix
{
private:
int row;
int column;
public:
int getRows()
{
return row;
}
int getColumns()
{
return column;
}
void print_matrix()
{
for(int i = 0; i < row; i++)
{
cout<<"\n";
for(int j = 0; j < column; j++)
cout<<matrix[i][j]<<"\t";
}
}
Matrix(int row, int column);
};
Matrix::Matrix(int row, int column)
{
this->row = row;
this->column = column;
int** matrix = new int*[row];
for(int i = 0; i < row; i++)
matrix[i] = new int[column];
for(int i = 0; i < row; i++)
for(int j = 0; j < column; j++)
matrix[i][j] = (i+j)*2*3/4;
for(int i = 0; i < row; i++)
delete[] matrix[i];
delete[] matrix;
}
at this point i dont know how to print my matrix, or work with him. In method "print_matrix" my compilator said that "'matrix was not declarated in this scope'".
You are deleting the allocated matrix in the constructor itself. To make it work,
add a member int**matrix in the class. And then do the allocation in constructor and delete it in destructor.
To add it further, even if you didn't delete the matrix then you would end up with the same error. The variable you have declared and used in the constructor - it's lifetime ends when the constructor ends.
Now instead of using pointer and allocating to it, why not use vector?
In that case you will keep std::vector v; as a member variable in the class and then resize it in constructor.
v.resize(row);
for (int i = 0; i < row; ++i)
v[i].resize(col);

Creating an n by n grid, where each element is a pointer to an object

class ClassName {
A* grid[][];
}
I'm getting that "declaration of ‘grid’ as multidimensional array must have bounds for all dimensions except the first" error. The issue is I won't know the dimensions until I run the program, where the size is one of the arguments.
The instructions state that each element of the grid should be an A* -- i.e., a pointer to an object of type A.
How can I do this?
You could opt to define grid this way: A*** grid;. Of course, you'd have to dynamically allocate memory with this setup:
class ClassName {
A*** grid;
int nCols, nRows;
public:
ClassName(int cols, int rows) {
nCols = cols;
nRows = rows;
grid = new A**[nCols];
for (int i = 0; i < nCols; i++) {
grid[i] = new A*[nRows];
for (int j = 0; j < nRows; j++) {
grid[i][j] = nullptr;
}
}
}
~ClassName() {
for (int i = 0; i < nCols; i++) {
delete[] grid[i];
}
delete[] grid;
}
};

How properly dynamically allocate 2d array inside void function?

I 'm still newbie in C++, so don't be mean to me. I would like to know how to initialize 2 dimentional array in the void function.
This is my example code but it gives me exceptions about access violation locations instead:
#include "stdafx.h"
void matrixInit(char***);
void matrixDel(char**);
void main(void){
char** game=0;
matrixInit(&game);
matrixDel(game);
return;
}
void matrixInit(char*** matrix) {
matrix = new char**[3];
for (int i(0); i < 3; i++) {
matrix[i] = new char*[3];
for (int j(0); j < 3; j++)
*matrix[i][j] = '0';
}
return;
}
void matrixDel(char** matrix) {
for (int i(0); i < 3; i++)
delete[] matrix[i];
delete[] *matrix;
return;
}
Props to #fireant for the help with allocating the array. After some research and debugger plays, I figure all it out. I hope this solution will help someone in the future!
#include "stdafx.h"
using namespace std;
int** matrixInit(int, int);
void matrixInit(int***, int, int);
void matrixDel(int**, int);
void matrixFill(int**, int, int);
void matrixPrint(int**, int, int);
void main(void) {
const int rows = 3, cols = 3;
int** game;
matrixInit(&game, rows, cols); //Void allocation
//game = matrixInit(rows, cols); //Alternative allocation
matrixFill(game, rows, cols);
matrixPrint(game, rows, cols);
matrixDel(game, rows);
cout << endl << "Passed!"; //<iostream> lib required
_getch(); //<conio.h> lib required
return;
}
//Dynamical array allocation void function
void matrixInit(int*** matrix, int nRow, int nColumn) {
(*matrix) = new int*[nRow];
for (int i(0); i < nRow; i++)
(*matrix)[i] = new int[nColumn];
}
//Dynamical array allocation pointer return function
int** matrixInit(int nRow, int nColumn) {
int** matrix = new int*[nRow];
for (int i(0); i < nRow; i++)
matrix[i] = new int[nColumn];
return matrix;
}
//Dynamical array deallocation void function
void matrixDel(int** matrix, int nRow) {
for (int i(0); i < nRow; i++)
delete[] matrix[i];
delete[] matrix;
}
//Fill array void function
void matrixFill(int** matrix, int nRow, int nColumn) {
for (int i(0); i < nRow; i++)
for (int j(0); j < nColumn; j++)
matrix[i][j] = (j + 1) + (i * nRow);
}
//Print array void function
void matrixPrint(int** matrix, int nRow, int nColumn) {
for (int i(0); i < nRow; i++)
for (int j(0); j < nColumn; j++)
cout << "[" << i << "][" << j << "] = " << matrix[i][j] << endl;
}
You're almost there,
void matrixInit(char*** matrix) {
(*matrix) = new char*[3];
for (int i(0); i < 3; i++) {
(*matrix)[i] = new char[3];
for (int j(0); j < 3; j++)
(*matrix)[i][j] = '0';
}
return;
}
You're passing the address matrixInit(&game), but matrix = new char**[3]; is overwriting the passed address. Thus, game in main is not pointing to the allocated memory. You could have written void matrixInit(char*** const matrix) to make sure you don't change the address accidentally inside the function. As a practice try to fix your delete function.