"dynamic constructor" in c++ - c++

i am new to classes in C++ and i need to create a class "Plot" which has a method that reads in data from a file and creates a 3d grid.
i understand that you can make "default" constructors with default values or you can create a special constructor with predefined values.
in my "private" section, i have:
int nx; // number of "x" values
int ny; // number of "y" values
int nz; // number of "z" values
double* grid; // one dimensional array which stores nx*ny*nz values
double tgrid(int ix, int iy, int iz); // function which searches grid and returns value
now, i want to create my "plot" object and then AFTER that, dynamically create the "grid" array. is it possible to do this? or will i need to declare the size of the array "grid" when i first create "plot"?

Use std::vector grid; as your member. Then you can use grid.resize(nx*ny*nz) to force the size you want or use grid.push_back(value); for each value you want to add to the array.

It is possible:
class Plot{
int nx; // number of "x" values
int ny; // number of "y" values
int nz; // number of "z" values
double* grid; // one dimensional array which stores nx*ny*nz values
double tgrid(int ix, int iy, int iz); // function which searches grid and returns value
public:
Plot()
{
grid = NULL;
}
~Plot()
{
delete[] grid;
}
void init(int x, int y, int z)
{
delete[] grid; //make sure no memory leaks since grid might have already been allocated
nx = x;
ny = y;
nz = z;
grid = new double[nx*ny*nz];
}
};
After the construction, just call the method init:
Plot p();
p.init(2,3,4);
EDIT:
You should however consider Mark B's answer. I would also use something from std:: rather than a dynamically allocated array. Much easier to manage.
EDIT2:
As per Constantinius' answer, avoid init() methods when you can. If you specifically need the initalization AFTER construction, use it, otherwise keep all initialization logic in the constructor.

It depends on how your Plot class should be used. If you consider it necessary to create objects of this class only with valid sizes you should not allow a default constructor. You do this by defining your own constructor like that:
public:
Plot(int _nx, int _ny, int _nz) : nx(_nx), ny(_ny), nz(_nz)
{
// initialize your array
grid = new double[nx*ny*nz];
}
also don't forget your destructor to clear the allocated memory:
~Plot()
{
delete[] grid;
}

class Plot {
int nx; // number of "x" values
int ny; // number of "y" values
int nz; // number of "z" values
double* grid; // one dimensional array which stores nx*ny*nz values
double tgrid(int ix, int iy, int iz); // function which searches grid and returns value
public:
/* default constructor */
Plot() : nx(0), ny(0), nz(0), grid(NULL) { }
/* rule of five copy constructor */
Plot(const Plot& b) : nx(b.nx), ny(b.ny), nz(b.nz) {
int max = nx*ny*nz;
if (max) {
grid = new double(max);
for(int i=0; i<max; ++i)
grid[i] = b.grid[i];
} else
grid = NULL;
}
/* rule of five move constructor */
Plot(Plot&& b) : nx(b.nx), ny(b.ny), nz(b.nz) grid(b.grid) { b.grid = NULL; }
/* load constructor */
Plot(std::istream& b) : nx(0), ny(0), nz(0), grid(NULL) { Load(b); }
/* rule of five destructor */
~Plot() { delete[] grid; }
/* rule of five assignment operator */
Plot& operator=(const Plot& b) {
int max = b.nx*b.ny*b.nz;
double* t = new double[max];
for(int i=0; i<max; ++i)
t[i] = b.grid[i];
//all exceptions above this line, NOW we can alter members
nx = b.nx;
ny = b.ny;
nz = b.nz;
delete [] grid;
grid = t;
}
/* rule of five move operator */
Plot& operator=(Plot&& b) {
nx = b.nx;
ny = b.ny;
nz = b.nz;
delete [] grid;
grid = b.grid;
b.grid = NULL;
}
/* always a good idea for rule of five objects */
void swap(const Plot& b) {
std::swap(nx, b.nx);
std::swap(ny, b.ny);
std::swap(nz, b.nz);
std::swap(grid, b.grid);
}
/* your load member */
void Load(std::istream& in) {
//load data
//all exceptions above this line, NOW we can alter members
//alter members
};
};
int main() {
Plot x; //default constructor allocates no memory
Plot y(x); //allocates no memory, because x has no memory
Plot z(std::cin); //loads from stream, allocates memory
x = z; //x.grid is _now_ given a value besides NULL.
}
This answers your questions I think. Still: use a std::vector.

Related

Trouble Finding The Segmentation Fault Cause(s)

The code keeps giving segmentation fault ( core dropped ) error
I have feel like something is wrong with the getNumberParticles() ; as when i just have return 0 as the function definition there is no error but if i return anything else but 0 theres an error
also if you will tell me to use gdb
its a multiple file program with one main
im not sure how to debug it like that
particleList.cpp
ParticleList::ParticleList() {
numParticles = 0;
particles[500] = {};
}
// ParticleList::ParticleList(int rows, int cols){
// numParticles = 0;
// particles[rows * cols * 4] = {};
// }
ParticleList::ParticleList(const ParticleList& obj){
}
// Clean-up the particle list
ParticleList::~ParticleList() {
for(int i = 0 ; i < 500 ; i++){
delete particles[i];
}
}
// Number of particles in the ParticleList
int ParticleList::getNumberParticles() {
numParticles = 0;
for(int i = 0 ; i < 500 ; i++){
if(particles[i] != nullptr){
numParticles++;
}
}
return this->numParticles;
}
// Get a pointer to the i-th particle in the list
ParticlePtr ParticleList::get(int i) {
return particles[i-1];
}
// Add a particle (as a pointer) to the list
// This class now has control over the pointer
// And should delete the pointer if the particle is removed from the list
void ParticleList::add_back(ParticlePtr particle) {
int quantity = getNumberParticles();
particles[quantity]= particle;
}
// Remove all particles from the list
void ParticleList::clear() {
for(int i = 0 ; i < 500 ; i++){
particles[i]= nullptr;
}
}
ParticleList.h
#ifndef COSC_ASS_ONE_PARTICLE_LIST
#define COSC_ASS_ONE_PARTICLE_LIST
#include "Particle.h"
#include "Types.h"
class ParticleList {
public:
/* */
/* DO NOT MOFIFY ANY CODE IN THIS SECTION */
/* */
// Create a New Empty List
ParticleList();
ParticleList(const ParticleList& obj); //Copy Construcor
// Clean-up the particle list
~ParticleList();
// Number of particles in the ParticleList
int getNumberParticles();
// Get a pointer to the i-th particle in the list
ParticlePtr get(int i);
// Add a particle (as a pointer) to the list
// This class now has control over the pointer
// And should delete the pointer if the particle is removed from the list
void add_back(ParticlePtr particle);
// Remove all particles from the list
// Don't forget to clean-up the memory!
void clear();
/* */
/* YOU MAY ADD YOUR MODIFICATIONS HERE */
/* */
ParticleList(int rows, int cols);
/* This is a suggestion of what you could use. */
/* You can change this code. */
private:
// particle* particles[300]
//Array of pointers to particle objects
ParticlePtr particles[500];
int numParticles;
};
There are a few things wrong with your class:
I don't see anything it provides that std::vector<ParticlePtr> doesn't also provide (correctly).
You have not provided assignment operator, and thus violated the rule of 3.
Your copy constructor is incorrect, and doesn't initialize any of your members.
Your get method implements 1-based indexing, which is very likely to confuse everybody.
It is very likely that issue 2 or 3 above is the root cause of your crash.
But issue 1 should be enough to throw away this code and replace it with std::vector.

cant figure out how to acces these elements

this is my header
#include <SDL.h>
class Grid
{
public:
int** Cells;
int x;
int y;
SDL_Color* palette[255];
Grid(int,int,int);
~Grid();
void DrawGrid(SDL_Renderer*);
void SetPalette(int c, int r, int g, int b, int a);
};
and this is my source:
Grid::Grid(int a,int b,int s)
{
std::cout << "grid constructed";
x = a;
y = b;
Grid::Cells = (int**) malloc(x*s);
for (int i = 0;i < x;i++)
{
Grid::Cells[i] = (int*)malloc(y*s);
}
SetPalette(1, 255, 255, 255, 0);
}
void Grid::DrawGrid(SDL_Renderer* renderer)
{
std::cout << Grid::palette[Cells[i][o]].r << " : " << Cells[i][o];
SDL_SetRenderDrawColor(renderer, palette[Cells[i][o]].r, palette[Cells[i][o]].g, palette[Cells[i][o]].b, palette[Cells[i][o]].a);
SDL_RenderDrawPoint(renderer, i, o);
}
void Grid::SetPalette(int c, int r, int g, int b, int a)
{
palette[c].r = r;
i have this for green blue and alpha too
}
it says expression must have class type. how do i fix
i have tried hard to figure it out. so i hope i get an answer at least
i did remove some of the irellevant code so it wouldn't take too much space
You did not allocate memory for your palette elements. Without modifying data layout (which is bad, see below), you'll need at least allocate elements in your constructor (prior to SetPalette):
for(int i = 0; i != 255; i++) {
palette[i] = new SDL_Color;
}
(you will also need to release this memory e.g. in destructor).
With palette declared as SDL_Color* palette[255];, expression palette[c] have type SDL_Color*. Accessing structure field with . operator needs structure, not a pointer - so direct solution is palette[c]->r (or manually dereferencing and using ., but that's exactly what -> does).
However allocating a lot of so small objects have a relatively high cost and in given example there is no point to do so. If your palette size is constant (as it is) you could just use SDL_Color palette[255] and remove all allocation/deallocation code (and there will be no need for -> since type of palette[c] is now SDL_Color). If size isn't known at compile time - you can allocate array of colours with a single allocation (malloc or new[]). And if size is changing during runtime, it is probably easier to use vector.

Array without parameters in c++

I'm pretty new in c++ althought a bit experienced in java, and my problem it's the next one:
I'm doing a sudoku project where I'm creating an abstract data type of the box and the board. In the board one, I'm creating a bidimesional array of boxes, but when I want to create it as a public data so I can use it in the whole class and not only in the board constructor.
I'm creating it in the board constructor because If I don't create it there, I have no way of knowing the value of each dimension, and if I create the variable Box box[int][int] where I can use it in the class, I've got no way of knowing the dimensions. It'll be better understandable with some code.
This code allows me to create the Box array with the dimensions I want, because it's in the board constructor than when it's created it has as a parameters the number of boxes, but it don't let me use the "casilla" variable in the other part of the class nor other classes:
class tablero{
int filas;
int columnas;
public:
tablero (int filas, int columnas){
this->filas = filas;
this->columnas =columnas;
Casilla casilla[filas][columnas];
}
Casilla getCasilla(int n, int m){
return casilla[n][m]; <- Here shows an error because casilla cannot be resolved.
}
And this other code lets me use the casilla variable, but I have to give it the parameters to the dimensions before I know them:
class tablero{
int filas;
int columnas;
public:
Casilla casilla[0][0];
tablero (int filas, int columnas){
this->filas = filas;
this->columnas =columnas;
}
Casilla getCasilla(int n, int m){
return casilla[n][m];
}
No error, but the dimensions of the casilla array have to be given before I know them, and so, they may be the wrong ones (because the board may have different dimensions.
It's the first time I'm programming in c++, and I'm really frustated with this problem, can anyone help me to find a way to make it so it works both ways? (I already tried to leave both dimensions empty and then in the constructor put casilla[][] = Casilla cas[filas] [columnas] but it gives me an error..)
Thanks for the help everyone. Also, If you think the title is not clear enough, you can suggest one and I'll change it.
The Casilla code is this one:
class Casilla{
int fila;
int columna;
int numero;
public:
// constructor
Casilla(int fila, int columna,int numero)
{
this->fila = fila;
this->columna = columna;
this->numero = numero;
}
};
Thanks everyone for your answers, I've already found the answer I needed from 3 different people. I can't upvote all of you because I still don't have 15 reputation, but when I have it i'll upvote you all. Thanks for all your answers, really. I just need to know what I commented on the checked answer and it'll be all answered.
A solution with an array
//----------------------------------------------------------------------------
#include <iostream>
#include <iomanip>
//----------------------------------------------------------------------------
class Casilla
{
int fila;
int columna;
int numero;
public:
// default constructor
Casilla()
{
this->fila = -1;
this->columna = -1;
this->numero = 0;
}
int GetNumero() {return numero;}
void SetCasilla (int _fila, int _columna) //set a cell position
{
fila = _fila;
columna = _columna;
}
void SetCasilla (int _numero) //set a cell value
{
numero = _numero;
}
void SetCasilla (int _fila, int _columna, int _numero) //set a cell position and value
{
fila = _fila;
columna = _columna;
numero = _numero;
}
};
class Tablero
{
int filas;
int columnas;
Casilla **casilla;
public:
Tablero (int filas, int columnas)
{
this->filas = filas;
this->columnas =columnas;
casilla = new Casilla* [filas];
for (int i = 0; i<filas; i++)
casilla[i] = new Casilla [columnas];
for (int i = 0; i<filas; i++)
for (int j = 0; j<columnas; j++)
casilla[i][j].SetCasilla(i,j); //set the right position for each cell
//the values = 0 by default
}
//destructor
~Tablero()
{
for (int i = 0; i<filas; i++)
delete [] casilla[i];
delete [] casilla;
}
//set a cell value in the table
void ChangeCasillaValue (int _fila, int _columna, int _numero)
{
casilla[_fila][_columna].SetCasilla (_numero);
}
Casilla getCasilla(int n, int m)
{
return casilla[n][m];
}
void PrintTablero ()
{
for (int i = 0; i<filas; i++)
{
for (int j = 0; j<columnas; j++)
std::cout << std::setw(5)<<casilla[i][j].GetNumero();
std::cout << "\n";
}
std::cout << "\n";
}
};
//----------------------------------------------------------------------------
int main()
{
int N = 5, M = 6;
Tablero table(N, M);
table.PrintTablero();
table.ChangeCasillaValue(1,1,-5); //change value in cell(1,1)
table.PrintTablero();
std::cin.get();
return 0;
}
//-----------------------------------------------------------------------------
You have to add a bunch of setters and getters of your own.
But, as a draft, it works.
C-style array dimensions must be known at compile-time in C++. So there is no variant of Casilla casilla[filas][columnas]; that will work.
Instead you should use a container which can hold the data you want to put in it. Use of C-style arrays in C++ is discouraged because they have some strange behaviour and rules, they are mainly there for backwards compatibility.
The simplest option is a 1-dimensional array with runtime size, that is called vector:
class tablero{
int filas;
int columnas;
std::vector<Casilla> casilla;
public:
tablero (int filas, int columnas)
: filas(filas), columnas(columnas), casilla(filas * columnas)
{ }
Casilla getCasilla(int f, int c) const
{
return casilla[f * columnas + c];
}
};
Note the use of the constructor initializer list. You should provide initial values for class members this way, instead of using assignment statements inside the constructor.
In your first example, in your constructor, the line
Casilla casilla[filas][columnas];
declares casilla an array of arrays of Casilla objects local to your constructor. Once your constructor returns, casilla goes out of scope. There is no casilla member variable or local variable in your getCasilla function, so of course it cannot be resolved.
In your second example, your class has a public member casilla declared as 0 by 0 array of Casilla objects. Your getCasilla function would return the item in the nth row and mth column of the 0 by 0 array. In C++, there is no bound checking on array dereferences, so this is returning some out of bounds memory location and is very bad.
You can create dynamic C arrays yourself by using malloc and free, but since you are using C++ it will be easier to just use std::vector.
For example, you could use:
#include <iostream>
#include <vector>
class Casilla
{};
class tablero
{
int filas_;
int columnas_;
std::vector<std::vector<Casilla> > casilla_; // a vector of vectors of Casillas
public:
tablero(int filas, int columnas) : filas_(filas), columnas_(columnas),
casilla_(filas, std::vector<Casilla>(columnas))
// The above is an initialization list
// We initialize casilla_ as a vector of filas vectors of columnas Casillas
{}
std::vector<std::vector<Casilla> > getCasilla() const
{
return casilla_;
}
};
int main(int argc, const char* argv[])
{
tablero t(3, 3);
std::cout << "casilla rows: " << t.getCasilla().size() << std::endl;
std::cout << "casilla cols: " << t.getCasilla()[0].size() << std::endl;
return 0;
}
First Casilla casilla[filas][columnas]; needs to be a class variable so it's accessible to all methods.
Second the sizes of rows and columns must be a fixed number e.g Casilla casilla[9][9];
If it need to be dynamically allocated you could you Vectors or Vectors of Vectors.
If it's 2d array, you can still create it as 1d array, but depends which is best for your purposes.

Dynamically allocating array of objects

I need a double pointer of type DizzyCreature (my class) to point to an array of DizzyCreature pointers. When I run it I get "Access violation reading location 0x...". I can make a DizzyCreature* and call its member functions just fine, but when cannot run through the array and do the same thing for each obj.
I am following these instructions:
http://www.cplusplus.com/forum/beginner/10377/
Code
Server.h:
class Server
{
public:
Server(int x, int y, int count);
~Server(void);
void tick();
private:
DizzyCreature** dcArrPtr;
DizzyCreature* dcPtr;
int _count;
};
Server.cpp:
Server::Server(int x, int y, int count)
{
dcPtr = new DizzyCreature[count]; // this works just fine
dcArrPtr = new DizzyCreature*[count]; // this doesn't (but gets past this line)
_count = count;
}
Server::~Server(void)
{
delete[] *dcArrPtr;
delete[] dcPtr;
}
void Server::tick()
{
dcPtr->takeTurn(); // just fine
for (int i = 0; i < _count; i++) {
dcArrPtr[i]->takeTurn(); // crash and burn
}
}
EDIT:
The member function takeTurn() is in a parent class of DizzyCreature. The program makes it into the function, but as soon as it attempts to change a private member variable the exception is thrown. If it matters, DizzyCreature is of type GameCreature and WhirlyB as this is an assignment on MI.
You have allocated space for dcArrPtr, but didn't allocate every object in this array. You must do following:
Server::Server(int x, int y, int count)
{
dcPtr = new DizzyCreature[count];
dcArrPtr = new DizzyCreature*[count];
for ( int i = 0; i < count; i++ ) {
dcArrPtr[ i ] = new DizzyCreature;
}
_count = count;
}
Server::~Server(void)
{
for ( int i = 0; i < count; i++ ) {
delete dcArrPtr[ i ];
}
delete[] *dcArrPtr;
delete[] dcPtr;
}
This:
dcPtr = new DizzyCreature[count];
"creates" an array of DizzyCreatures, whereas:
dcArrPtr = new DizzyCreature*[count];
"creates" an array of pointers to DizzyCreatures, but crucially doesn't create instances for those pointers to point to.
The preferred solution is to use a standard container for tasks like this anyway though. If you really want to do it like this (and are aware that it's not best practice to do this manually) then you'll need a loop to call new for eachelement in the array of pointers.
You allocate an array of count pointers instead of an array of count objects.
Instead of
dcArrPtr = new DizzyCreature*[count];
you might want to
dcArrPtr = new DizzyCreature[count];
You're allocating an array of pointers, but those pointers aren't valid until you set them to something.
double **arr = new double*[10];
for(int i=0;i<10;++i) {
arr[i] = new double[10];
}
That said, when starting out with C++ you should probably avoid raw arrays and instead use std::array and std::vector:
class Server
{
public:
Server(int x, int y, int count);
void tick();
private:
std::vector<std::vector<DizzyCreature>> dcArrPtr;
std::vector<DizzyCreature> dcPtr;
};
Server::Server(int x, int y, int count)
{
dcPtr.resize(count);
dcArrPtr.resize(count);
}
void Server::tick()
{
dcPtr[0].takeTurn();
for (int i = 0; i < dcArrPtr.size(); i++) {
dcArrPtr[i][0].takeTurn();
}
}
Use a
std::vector<std::vector<DizzyCreature>>
Furthermore, if you want to use raw pointers (which I do not recommend), you'll have to allocate memory for each pointer in your array.
class A
{
std::vector<std::vector<int>> v_;
public:
A()
: v_(500, std::vector<int>(500))
{} // 500 x 500
};
class B
{
int** v_;
public:
B()
: v_(new int*[500])
{ // not even exception safe
for (int i = 500; i--; )
v_[i] = new int[500];
}
~B()
{
for (int i = 500; i--; )
delete[] v_[i];
delete[] v_;
}
};
If you would have seen the implementation of dynamic memory allocation of 2-Dimensional array . That would have given you a better insight of how to proceed in such cases . Most of the answers has already answered you what to do . But just go through any link and see how is memory allocated in case of 2-D array . That Will also help you .

What's the proper way to pass a pointer to a function for deletion?

I have a matrix declared like int **matrix, and I know that the proper way to pass it to a function to allocate memory should be like this:
void AllocMat(int ***mat, int size);
But now I need to delete these memory in another function and am not sure about what to pass:
void DeallocMat(int **mat, int size);
or
void DeallocMat(int ***mat, int size);
I think the second one should be right, but neither way gives me segmentation fault as I tried.
The question is tagged C++, and yet the answers only use the C subset...
Well, first of all, I would recommend against the whole thing. Create a class that encapsulates your matrix and allocate it in a single block, offer operator()(int,int) to gain access to the elements...
But back to the problem. In C++ you should use references rather than pointers to allow the function to change the argument, so your original allocate signature should be:
void AllocMat(int **&mat, int size);
And call it like:
int **matrix = 0;
AllocMat( matrix, 5 );
Or better, just return the pointer:
int **AllocMat( int size );
int **matrix = AllocMat( 5 );
For the deallocation function, since you don't need to modify the outer pointer, you can just use:
void DeallocMat( int**mat, int size ); // size might be required to release the
// internal pointers
Now, for a sketch of the C++ solution:
template <typename T> // no need to limit this to int
class square_matrix {
const unsigned size;
T * data;
public:
square_matrix( unsigned size ) : size(size), data( new T[size*size]() ) {}
square_matrix( matrix const & m ) : size( m.size ), data( new T[m.size*m.size] ) {
std::copy( m.data, m.data+size*size, data );
}
~matrix() {
delete [] data;
}
T const & operator()( unsigned x, unsigned y ) const {
// optional range check and throw exception
return data[ x + y*size ];
}
void set( unsigned x, unsigned y, T const & value ) {
// optional range check and throw exception
data[ x + y*size ] = value;
}
};
First is correct. But your real problem is that you are using pointers when there are better alternatives. For a 2d matrix you should use a vector of vectors
#include <vector>
typedef std::vector<std::vector<int> > Matrix;
Matix m;
Now there is no need to delete anything, so one less thing to go wrong.
void DeallocMat(int **mat, int size) - allows you to deallocate memory (since you have passed the value of mat only allowing to deallocate memory but not change mat)
void DeallocMat(int ***mat, int size) - allows you to deallocate memory and change the value of mat to NULL (since you have now passed a pointer to mat allowing you to change its value)
The extra "*" just handles the pointer to be behaved as call by reference. If you want to get the output from your function, you need an extra "*" in your declaration. In this case, you should pass the reference of your pointer (using &) to these functions.
The reason why you required to pass a pointer to double pointer because your local variable must required to reflect with the new updated memory
void Foo(int * a)
{
a = new int[10];
}
int main()
{
int *a = 0;
Foo( a );
}
Now the memory will be allocated but the pointer A will not be update because the value of pointer A is simply copied to another pointer variable which is parameter of Foo. Once the Foo is returned, a will remain 0. To make it refect that, you should write code like follows
void Foo(int ** a)
{
*a = new int[10];
}
int main()
{
int *a = 0;
Foo( &a );
}
Here you're passing the address of a pointer. The which means that, the value which contains in the pointer will be updated from the Foo function.You can debug through and see how it works.
If you're sure that you will not access the pointer anymore, please use the first type. Otherwise use the second one. Make sure that you set the pointer to NULL to avoid further memory corruptions or dangling pointers.
The thing that confuses me about your question is that most people would not declare a matrix as an int **. The reason for this is that you would be forced to then allocate it in a loop. Your allocation function would require two parameters, which are the dimensions of the array like this:
void AllocMat(int *** mat, int n, int m) {
int ** result = new int * [ n ];
for (int x=0; x<n; x++) {
result[x] = new int [ m ];
}
*mat = result;
}
If this were the case, the corresponding deallocation function would require knowledge of the size of n as follows:
void DeallocMat(int *** mat, int n) {
if (mat == NULL || *mat == NULL) return;
int ** tmp = *mat;
for (int x=0; x<n; x++) {
if (tmp[x] != NULL) delete [] tmp[x];
}
delete [] tmp;
*mat = NULL;
}
With this approach, you could access your matrix like this:
int ** mat = NULL;
AllocMat(&mat, n, m);
for (int x=0; x<n; x++) {
for (int y=0; y<m; y++) {
mat[x][y] = 1;
}
}
DeallocMat(&mat, n);
Usually, people allocate matrices as a single buffer of memory to avoid extra allocations and pointer indirections, which is how I recommend you do it. In that case, you allocation function would look like this:
void AllocMat2(int ** mat, int n, int m) {
*mat = new int [ n * m ];
}
And the corresponding deallocation function like this:
void DeallocMat2(int ** mat) {
if (mat != NULL && *mat != NULL) {
delete [] *mat;
*mat = NULL;
}
}
And you would access it follows:
int * mat2 = NULL;
AllocMat2(&mat2, n, m);
for (int x=0; x<n; x++) {
for (int y=0; y<m; y++) {
mat2[x * n + y] = 1;
}
}
DeallocMat2(&mat2);
Either way works, but if you pass a pointer to the pointer you need to dereference it first. And the size parameter is redundant.
void DeallocMat(int **mat)
{
delete[] mat;
}
void DeallocMat(int ***mat)
{
delete[] *mat;
*mat = NULL;
}