How properly dynamically allocate 2d array inside void function? - c++

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.

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

Arbitrary matrix dimension in matrix class

The task is as follows: Describe the class "matrix of numbers" with component data: the dimensions of the matrix, a pointer to the elements. Overload operations: << (matrix output to the screen), + (addition of matrices), unary ¬– (change the sign of each element), / = (divide each element by a number). I performed it, and performed it correctly, but you need to set the matrix dimension from the keyboard, and as you can see, it is set in advance for me [3] [3]. It sounds pretty simple, but something I'm really dumb. Thanks in advance for your help. Here is the code:
#include "pch.h"
#include <iostream>
using namespace std;
class Matrix
{
public:
Matrix()
{
int Table[3][3];
}
int Table[3][3];
void Create()
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
Table[i][j] = 10;
}
};
ostream& operator <<(ostream& t, Matrix a)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
t << a.Table[i][j] << " ";
t << "\n";
}
return t;
}
Matrix& operator /=(Matrix& a, int num)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a.Table[i][j] /= num;
return a;
}
Matrix& operator -(Matrix& a, int empty)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a.Table[i][j] = -a.Table[i][j];
return a;
}
Matrix& operator +(Matrix& a, Matrix b)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
a.Table[i][j] += b.Table[i][j];
return a;
}
int main()
{
int u;
setlocale(LC_ALL, "Russian");
Matrix Example;
Example.Create();
Matrix Example1;
Example1.Create();
cout << Example;
cout << Example1;
cout << "Сумма матриц: "<<endl;
cout << Example + Example1;
Example - 1;
Example1 - 1;
cout<< Example + Example1;
cout << "На сколько вы хотите её поделить?\n";
cin >> u;
Example /= u;
Example1 /= u;
cout << Example;
cout << Example1;
}`
You need to dynamically create the matrix.
In order to this you need to use pointers(*). Change int table[3][3]
double table**;
An example of how it could be implemented (note that I use matrix instead of table)
class Matrix {
private:
double** matrix;
int col;
int row;
public:
Matrix(){};
void Create(int row, int col);
};
void Matrix::Create(int row_, int col_){
double val = 0.0;
col = col_; // initalize private members
row = row_;
matrix = new double*[row]; // Create a new array of size row_
for(int i = 0; i < row; i++)
{
matrix[i] = new double[col]; // Create new cols of size col (inside array of row)
}
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
matrix[i][j] = val;
val = val + 1.0;
}
}
}
I tried to reuse your design for simplicity, but I really suggest that you try to specify the dimensions of the matrix in a constructor instead and maybe even construct the matrix in it as well.
Something like this:
Matrix(int row_, int col_) : row(row_), col(col_) {*/ create matrix here /*};
You can skip the "create matrix here" part and use your own Create() if you want to.
You need dynamic memory allocation for that. I won't fiddle around with pointers (new / delete) unless you are explicitly told to. As a beginner you should probably use the standard template library (STL) tools:
#include <vector> and use std::vector<std::vector<int>> Table instead of int Table[3][3]. Then write a constructor like this:
Matrix(std::size_t rows, std::size_t cols)
{
Table.resize(rows);
for (unsigned int i = 0; i < Table.size(); ++i)
Table[i].resize(cols);
}
You can additionally store the dimension of the matrix, but there is no need to do it since you can get the information from the vectors. Replace the hardcoded dimensions in all loops by the corresponding dynamic sizes (stored or extracted from the vectors). For example:
Matrix& operator +(Matrix& a, Matrix b)
{
unsigned int rows = a.Table.size();
unsigned int cols = a.Table[0].size();
for (unsigned int i = 0; i < rows; i++)
for (unsigned int j = 0; j < cols; j++)
a.Table[i][j] += b.Table[i][j];
return a;
}
However, this vector of vectors is not really effective. Better would be a single vector but I guess for a beginner it is okay.
Greetings

How to use pointer to pointer for passing matrix?

Passing matrix as a pointer to pointer to function not working.
#include <stdio.h>
void printMatrix(int **matrix, int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
printf("%d ", matrix[i][j]);
printf("\r\n");
}
}
void printM (size_t row, size_t col, int matrix[3][4])
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
printf("%d ", matrix[i][j]);
printf("\r\n");
}
}
int main()
{
int M[3][4];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 4; j++)
M[i][j] = 4*i+j;
printM(3, 4, M);
int *row = *M;
printMatrix(&row, 3, 4); //not working
}
Function printM works, but I would like to know how to use pointer to pointer correctly, thanks for help.
First of all, thank-you for this question. It is a good review of how C does multi-dimensional arrays. Also, it is OK to do double pointers. Remember an array reference is equivalent to a pointer, such as: a[0] and *a both refer to the first element of int a[12]; where *a is the de-referencing of pointer a. And so, &M is a the address of the pointer M when M is declared as int M[3][4];
I modified your code by adding a few comments for clarity and so that it would run in Eclipse using a C compiler from Microsoft, specifically, int declarations where moved out of the for statements. Other than that it is the same as what you originally wrote with a change to the printMatrix declaration and how it is invoked.
Hope this helps, please ask if more questions...
#include <stdio.h>
void printMatrix(int (*matrix)[3][4], int row, int col)
{
int i, j;
// point t so that when de-referenced it is at
// the matrices first element
int *t = (*matrix)[0];
printf("\n");
for (i = 0; i < row; i++)
{
// in C matrices are stored in Row Major form, so
// per K&R just sequentially loop thru (*t)[12]
for (j = 0; j < col; j++) {printf("%d ", *t++);}
printf("\r\n");
}
} // end printMatrix
void printM (size_t row, size_t col, int matrix[3][4])
{
int i, j;
printf("\n");
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++) {printf("%d ", matrix[i][j]);}
// new line for next row
printf("\r\n");
}
}
int main()
{
int i,j;
// define a matrix with 3 rows and 4 columns
int M[3][4];
// fill-in the matrix with values
for (i = 0; i < 3; i++)
for (j = 0; j < 4; j++)
M[i][j] = 4*i + j;
// print the three rows and four columns of M
printM(3, 4, M);
printMatrix(&M, 3, 4); // Also Works
} // end main
void printMatrix(int *matrix, int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
printf("%d ", *(matrix+(i*col)+j);
printf("\r\n");
}
}
Don't do a double pointer.

How to delete this 2D Array in 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;
}
}