Matrix allocation, initialisation and deallocation

This code throws "Access violation reading location 0xCCCCCCCC" exception. It occurs due to nullpointer at line "p[i][j]=0.;". How could I handle the problem by changing only the underlined expressions in the commented lines. Basically, it should correctly allocate, initialize and deallocate a matrix.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
using namespace std;
void dealloc(double ****p, int n)
{
	for (int i = 0; i<n; i++)
		delete[](**p)[i];
	delete[] *p;	//1
}
int init(double **p, int n)
{
	for (int i = 0; i<n; i++)
		for (int j = 0; j<n; j++)
			p[i][j] = 0.;
	return n;
}
int alloc(double **p)	//2
{
	const int size = 100;
	p = new double*[size];	//3
	for (int i = 0; i<size; i++)
		p[i] = new double[size];
	return size;
}
int main(int argc, char* argv[])
{
	double **A;
	double ***p = &A;
	dealloc(&p, init(A, alloc(A)));	//4
	return 0;
}
msaeternal wrote:
It occurs due to nullpointer at line "p[i][j]=0.;"

0xCCCCCCCCC is not a null pointer. It's an uninitialized pointer being dereferenced, so your evaluation of the problem is not correct. Furthermore, one cannot correct the problem by "changing only the underlined expressions."

In the alloc function, it should be obvious that we wish to change the address contained by A so passing A by value is not going to get the job done. One could pass by reference, or one could pass the address of the A variable to the function. From the style of your code it appears as if the latter would be the solution, so the function prototype for alloc would be: int alloc(double*** p).
> In the alloc function, it should be obvious that we wish to change the address contained by A
init(A, alloc(A))
undefined behaviour (evaluation order)
OK, I've solved it as seen below. I've changed underlined parts only and error went away, but still couldn't get the point though.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
using namespace std;
void dealloc(double ****p, int n)
{
	for (int i = 0; i<n; i++)
		delete[](**p)[i];
	delete[] **p;	//1
}
int init(double **p, int n)
{
	for (int i = 0; i<n; i++)
		for (int j = 0; j<n; j++)
			p[i][j] = 0.;
	return n;
}
int alloc(double **&p)	//2
{
	const int size = 100;
	p = new double*[size];	//3
	for (int i = 0; i<size; i++)
		p[i] = new double[size];
	return size;
}
int main(int argc, char* argv[])
{
	double **A;
	double ***p = &A;
	dealloc(&p, init(A, alloc(A)));	//4
	return 0;
}
You haven't "solved it." You've only made it compile. The code is still a bit nonsensical and results in undefined behavior. I would expect such code to look more like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void dealloc(double** mat, int n)
{
    for (int i = 0; i < n; ++i)
        delete [] mat[i];
    delete [] mat;
}

double** init(double** mat, int n)
{
    for (int i = 0; i<n; i++)
        for (int j = 0; j<n; j++)
            mat[i][j] = 0.0;

    return mat;
}

double** alloc(int size)
{
    double** mat = new double*[size];

    for (int i = 0; i < size; ++i)
        mat[i] = new double[size];

    return mat;
}

int main(int argc, char* argv[])
{
    const int sz = 100;

    double** A = alloc(100);
    init(A, sz);
    dealloc(A, sz);

    // or, with no undefined behavior:

    dealloc(init(alloc(sz), sz), sz);
}
Topic archived. No new replies allowed.