GIDForums  

Go Back   GIDForums > Computer Programming Forums > C Programming Language
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 20-Feb-2004, 07:37
cjwatchdog cjwatchdog is offline
New Member
 
Join Date: Feb 2004
Posts: 2
cjwatchdog is on a distinguished road
Question

3D array dynamic memory allocation


I am writing a code to read in a 3D gray scale image file into a program. I got a stack fault error when I originally wrote the code due to the size of the image file. I then tried to use malloc to allocate sufficient memory. The code compiles but I get several warnings telling me "differs in levels of indirection". I do not think I am doing this correctly. I have included the relevant parts of the code below. Any help would be appreciated.

CPP / C++ / C Code:
unsigned char ***Image=NULL;
int Slice, Row, Voxel;
int i,j,k;

/* allocate space for 3D image array */
/* make sure that the largetst dimension goes in the initial array allocation */

Image = (unsigned char ***)malloc(Row*sizeof(unsigned char *)); /* may need another * in sizeof */

/* allocate space for each slice */
for(i=0; i < NB_SLICES; i++)
{
 Image[i]=(unsigned char *)malloc(Slice*sizeof(unsinged char *));
}

/* allocate space for each row */
for(j=0; j < NB_ROWS; j++)
{
 Image[i][j]=(unsigned char *)malloc(Row*sizeof(unsinged char *));
}

/* allocate space for each voxel*/
for(k=0; k < NB_VOXELS; k++)
{
 Image[i][j][k]=(unsigned char *)malloc(Voxel*sizeof(unsinged char *));
}

/* to free allocated memory at end of program */
for(i=0; i<NB_SLICES; i++)
{
	free(Image[i]);
}

Thanks.
Last edited by dsmith : 20-Feb-2004 at 07:47. Reason: Added C syntax highlighting
  #2  
Old 20-Feb-2004, 08:06
dsmith's Avatar
dsmith dsmith is offline
Senior Member
 
Join Date: Jan 2004
Location: Utah, USA
Posts: 1,351
dsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of light
Hello cj.

Wow! Three levels of indirection, my head hurts!

First, this call is probably giving you problems. Image[i] should return a char **. Also, notice that you have an unsinged char as opposed to an unsigned char.
CPP / C++ / C Code:

/* allocate space for each slice */
for(i=0; i < NB_SLICES; i++)
{
 Image[i]=(unsigned char *)malloc(Slice*sizeof(unsinged char *));
}

The whole thing should be more like: (assuming that your slices are first, followed by rows, followed by voxels

CPP / C++ / C Code:
Image = (unsigned char ***)malloc()malloc(Slice*sizeof(unsigned char ***));

for(i=0; j < NB_SLICES; i++)
{
 Image[i]=(unsigned char **)malloc(Row*sizeof(unsigned char **));
   for(j=0; j < NB_ROWS; j++)
   {
       Image[i][j]=(unsigned char *)malloc(Voxel*sizeof(unsigned char *));
    }
}

Once you get down to Image[i][j][k], what you are actually looking at is the charecter itself. It can be pretty confusing.

What would really help I think to look at this is if you could also post your original code using the arrays if you have it. I am not quite sure what you are trying to "store" in this memory yet.
Last edited by dsmith : 20-Feb-2004 at 08:40.
  #3  
Old 20-Feb-2004, 10:42
cjwatchdog cjwatchdog is offline
New Member
 
Join Date: Feb 2004
Posts: 2
cjwatchdog is on a distinguished road

additional code


Here is some additional code so that you can see what I am trying to do with the arrays. As far as what I am doing, I am writing a radiation transport code to calculate energy absorbtion using a CT image as a geometry. I am trying to read in bit wise a binary image file with different gray scale values (0 to 255). I am using the arrays so that each Image[i][j][k] is given a single value between 0 and 255. Then based upon the value I calculate position and distances between voxels along a path.
CPP / C++ / C Code:
  /*****************************/
   /* to read in the image file */
   /*****************************/
   ImageFile=fopen(IMAGE_FILE_NAME,"r");
   if (ImageFile==NULL) {
      printf("Error Opening File\n");
      }
   else {
      for(K=0; K<NB_SLICES; K++) {
         for(J=0; J<NB_ROWS; J++) {
             for(I=0; I<NB_VOXELS; I++) {
                if (!fread(&Medium,1,1,ImageFile)) {
                   printf("Error Reading File\n");
                   }
                else {
                   if ((Medium==BONE) || (Medium==MARROW) || Medium==FAT)) {
                      Image[i][J][K] = Medium;
                      }
                   else {
                      printf("Unknown medium in image\n");
                      }
                   }
                }
             }
          }
	  }
      fclose(ImageFile);

 /*******************************/
/* to randomly pick a starting position    */
/*******************************/
void SourceInBone(double *X, double *Y, double *Z,
unsigned char Image[NB_VOXELS][NB_ROWS][NB_SLICES])
   {
   int I,J,K;
   int SourceInBone;
   double RanNo;

   SourceInBone = FALSE;
   while (SourceInBone == FALSE) {
	  RanNo = drand48(RanNo);
      *X = VOXEL_SIZE * NB_VOXELS * RanNo;
	  RanNo = drand48(RanNo);
      *Y = ROW_WIDTH * NB_ROWS * RanNo;
      RanNo = drand48(RanNo);
      *Z = SLICE_THICK * NB_SLICES * RanNo;
      I = (int)(*X/VOXEL_SIZE);
      J = (int)(*Y/ROW_WIDTH);
      K = (int)(*Z/SLICE_THICK);
      if ( Image[i][J][K] == BONE ) {
         SourceInBone = TRUE;
         }
      }
   }

/****************************************************/
/* NextToBone - determines if voxel is next to bone */
/****************************************************/
int NextToBone(double X, double Y, double Z, unsigned char Image[NB_VOXELS][NB_ROWS][NB_SLICES])
{
   int I,J,K;
   int BesideBone;
   int Ipos, Ineg, Jpos, Jneg, Kpos, Kneg;
   int I1, I2, J1, J2, K1, K2;

	  I = (int)(X/VOXEL_SIZE);
      J = (int)(Y/ROW_WIDTH);
      K = (int)(Z/SLICE_THICK);
               
	  /* gives the values of the surrounding voxels */
      Ipos = I + 1;
	  Ineg = I - 1;
	  Jpos = J + 1;
	  Jneg = J - 1;
	  Kpos = K + 1;
	  Kneg = K - 1;

	  /* determines if the surrounding voxels are bone */
	  if(Image[Ipos][J][K] == BONE)
	  {
		  BesideBone = TRUE;
		  I1 = BONE;
	  }
	  if(Image[Ineg][J][K] == BONE)
	  {
		  BesideBone = TRUE;
		  I2 = BONE;
	  }
	  if(Image[i][Jpos][K] == BONE)
	  {
		  BesideBone = TRUE;
		  J1 = BONE;
	  }
	  if(Image[i][Jneg][K] == BONE)
	  {
		  BesideBone = TRUE;
		  J2 = BONE;
	  }
	  if(Image[i][J][Kpos] == BONE)
	  {
		  BesideBone = TRUE;
		  K1 = BONE;
	  }
	  if(Image[i][J][Kneg] == BONE)
	  {
		  BesideBone = TRUE;
		  K2 = BONE;
	  }
	  return (BesideBone);
} /* end NextToBone */

These are examples of how I am using the data in the image array. Please let me know if more information is needed and I can attach the whole code. Thanks.
Last edited by admin : 22-Apr-2007 at 09:50. Reason: Add C syntax highlighting
  #4  
Old 20-Feb-2004, 15:27
dsmith's Avatar
dsmith dsmith is offline
Senior Member
 
Join Date: Jan 2004
Location: Utah, USA
Posts: 1,351
dsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of light
I am afraid I gave you some rather bad advice earlier

I avoid multiple indirection because it can be pretty complicated. To C it is just a big block of memory and then you have to take care of the divisions. There is an excellent post here with a very good explanation of two levels of indirection. Basically, instead of being able to access your data like
CPP / C++ / C Code:
Image[i][J][K] = Medium;

You would need to do something like:
CPP / C++ / C Code:
*(Image + (NB_SLICES*K) + (NB_ROWS*J) + I) = Medium;

Also, you would need to allocate all of this memory as the same chunk of memory (ie - it needs to be sequential)
CPP / C++ / C Code:
Image = (char***)malloc(NB_SLICES*NB_ROWS*NB_VOXELS*sizeof(char));

which is exactly the same as using an array, except for the time that the memory is allocated. So after all this, you are probably back to the same problem. Your program either doesn't have access to this much contiguous memory or it can't reach it using standard memory allocation.

How big does your memory need to be? What O/S and compiler are you using? I don't know that a dynamic memory allocation will help...
 
 

Recent GIDBlogVista ?Widgets? on Windows XP by LocalTech

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
throwing an struct(with an array) through a function knakworstje C Programming Language 5 15-Feb-2004 16:20
c: array comparison jack C Programming Language 7 26-Jan-2004 11:21
Trying to create the game of life warny_maelstrom C Programming Language 10 21-Jan-2004 21:14
pointers and arrays jack C Programming Language 4 15-Jan-2004 12:27
Extra null element in an array samtediou MySQL / PHP Forum 2 11-Dec-2003 11:52

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 21:31.


vBulletin, Copyright © 2000 - 2010, Jelsoft Enterprises Ltd.