• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 329
  • Last Modified:

3 dimension array memory problem in C++

I want to have a 3 dimentional matrix of chars as matrix[i][j][k]
i is defined as MAXVAR_A, j and k are not known. There must be problem whit hte free() code because the first time I call the function and allocate memory is ok. But when I call the function for second or third time, i get memory error.

Here is the code:

char **matrix[MAXVAR_A];      


makearray(int MAXVAR_J,int MAXVAR_K)
{
int i,j,k;
      
      for (i=0;i<MAXVAR_A;i++)
            for (j=0;j<=MAXVAR_J;j++) matrix[i]=new char*;
      for (k=0;k<MAXVAR_K;k++)
            for (i=0;i<MAXVAR_A;i++)
                  for (j=0;j<=MAXVAR_J;j++) matrix[i][j]=new char;

.......
code that is working using matrix array
.......

      //free matrix
      for (i=0;i<MAXVAR_A;i++)
            for (j=0;j<=MAXVAR_J;j++) free(matrix[i][j]);
      for (x=0;x<=MAXVAR_J;x++)
            free(matrix[x]);
}

0
panos2009
Asked:
panos2009
  • 4
  • 3
  • 3
  • +3
2 Solutions
 
ZoppoCommented:
Hi  panos2009,

IMO the problem is you mix up C and C++ allocation/release functions.

Instead of 'free(...)' you have to use 'delete [] ...'

Hope that helps,

ZOPPO
0
 
ZoppoCommented:
BTW, the allocation you use doesn't do what you expect I guess - i.e. in the first loop you allocate MAXVAR_J times a 'char*' for each 'matrix[i]' - this doesn't make sense since only the last one will be left in 'matrix[i]'.
0
 
Infinity08Commented:
See here (C-style allocation) :
/* allocate : */

for (i = 0; i < MAXVAR_A; ++i) {
      matrix[i] = (char**) calloc(MAXVAR_J, sizeof(char*));
      for (j = 0; j < MAXVAR_J; ++j) {
            matrix[i][j] = (char*) calloc(MAXVAR_K, sizeof(char));
      }
}

/* de-allocate */

for (i = 0; i < MAXVAR_A; ++i) {
      for (j = 0; j < MAXVAR_J; ++j) {
            free(matrix[i][j]);
      }
      free(matrix[i]);
}

Open in new window

0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
ZoppoCommented:
And here's the same with C++ allocation:
void makearray(int MAXVAR_J,int MAXVAR_K)
{
	int i,j;

	for ( i = 0; i < MAXVAR_A; i++ )
	{
		matrix[i]=new char*[MAXVAR_J];

		for ( j = 0; j < MAXVAR_J; j++ )
		{
			matrix[i][j] = new char[MAXVAR_K];
		}
	}

	for ( i = 0; i < MAXVAR_A; i++ )
	{
		for ( j = 0; j < MAXVAR_J; j++ )
		{
			delete [] matrix[i][j];
		}

		delete [] matrix[i];
	}
}

Open in new window

0
 
itsmeandnobodyelseCommented:
To add to the last comments:

Instead of allocating memory for each "cell" of the matrix, you also could allocate one big piece of memory and point to that memory from your "cells".

0
 
itsmeandnobodyelseCommented:
And some code:


char **matrix[MAXVAR_A]; 
char * all = NULL;

void makearray(int MAXVAR_J,int MAXVAR_K)
{
    int i,j;
    all = new char[MAXVAR_A * MAXVAR_J * MAXVAR_K];
    char * p   = all;

    for ( i = 0; i < MAXVAR_A; i++ )
    {
       matrix[i]=new char*[MAXVAR_J];
       for ( j = 0; j < MAXVAR_J; j++ )
       {
          matrix[i][j] = p;
          p += MAXVAR_K;
       }
    }
}

void deletearray()
{
    int i = 0;
    for ( i = 0; i < MAXVAR_A; i++ )
        delete []matrix[i];
    delete [] all;
    all = NULL;
}

Open in new window

0
 
phyderousCommented:
What you guys think about this

int i =10,j=10,k=10;

char *a = new char [i*j*k];
char ***b = (char ***)a;

b[5][7][8] = 'c';

delete[] a //I think delete a should also work on most compillers
0
 
ZoppoCommented:
Well, that's quite similar to the last posted one:
> all = new char[MAXVAR_A * MAXVAR_J * MAXVAR_K];
> ...
>  delete [] all;
0
 
Infinity08Commented:
>> char ***b = (char ***)a;

dangerous cast.

>> b[5][7][8] = 'c';

won't work ;)
0
 
phyderousCommented:
work more then fine you may try and compile it to see for yourself

no reason for it not to work because there is no difference between b[5][7][8] and b[5*7*8]
this is what the compiler is doing the rest is only in the programmer head :)

[x] equals sizeof(type)*5 ...

I suggest you go back to the basics ...
0
 
phyderousCommented:
typeo

type a[x] equals sizeof(type)*x ...
0
 
TursilionCommented:
"there is no difference between b[5][7][8] and b[5*7*8]"

There is, actually...

b[x][y][z] means b + (x * (max_z) * (max_y)) + (y * (max_z)) + (z)

... where max_z is the size of the third dimension, and max_y is the size of the second dimension. You have to take the size of each dimension into account when calculating the memory offset, not just multiply the indexes.

However, the original author isn't looking for that level of detail, he's just trying to solve his memory allocation, which looks like was done nicely by Infinity08 and Zoppo. Itsmeandnobo also provides a suggestion of simplifying the allocation.

Arrays of this size start getting pretty hairy, though, sometimes it's worth revisiting why you need it.
0
 
panos2009Author Commented:
t
0
 
Infinity08Commented:
>> work more then fine you may try and compile it to see for yourself

Did you ? You might be surprised ... :)
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 4
  • 3
  • 3
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now