Thread: Fast dynamic allocation of 3D array

  1. #1
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715

    Fast dynamic allocation of 3D array

    Hi, I'm inspired with the similar thread on this board.
    I know how to allocate 2D array:
    Code:
    int main (void)
    {
    	int rows, cols, i, j;
    	int** matrix;
    	int* rawdata;
    
    	scanf("%d %d",&rows, &cols);
    	
    	rawdata = malloc(rows * cols * sizeof(int));
    	matrix = malloc(rows * sizeof(int*));
    	
    	for (i = 0; i < rows; ++i)
    	{
    		matrix[i] = &rawdata[i * cols];
    	}
    
    	for (i = 0; i < rows; ++i)
    	{
    		for (j = 0; j < cols; ++j)
    		{
    			scanf("%d",&matrix[i][j]);
    		}
    	}
    
    
    	free (matrix);
    	free (rawdata);
    
    	return 0;
    }
    Now, I don't know is it possible to extend this logic and to allocate 3D array. I tried something, but I cannot wrap my mind.
    here's my shot:
    Code:
    int main (void)
    {
    	int a, b, c, i, j,k;
    	int ***array_3D;
    	int* rawdata;
    	int** matrix;
    
    	scanf ("%d %d %d", &a, &b, &c);
    
    	rawdata = malloc (a * b * c * sizeof(int));
    
    	matrix = malloc (a * sizeof(int*));
    	
    	array_3D = malloc(c * sizeof(int**));
    
    	for (i = 0; i < a; ++i)
    	{
    		matrix[i] = & rawdata[i * b];
    	}
    
    	/* Now this is where all is messed up
    	for (i = 0; i < c; ++i)
    	{
    		/*Possible nested loop, but ???*/
    	}
    	
    	for (i = 0; i < a; ++i)
    		for (j = 0; j < b; ++j)
    			for (k = 0; k < c; ++k)
    				scanf("%d",&array_3D[i][j][k]);
    
    
    /*appropriate cleanup*/	
    	return 0;
    }
    Can you help me write it?
    I tried to do it myself but I didn't have success and I'm asking for your help.

    Thanks

    - Micko
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  2. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    This?
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #3
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Thanks, I'll try to understand that.

    - Micko
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  4. #4
    Registered User
    Join Date
    May 2005
    Posts
    207
    Hey Micko,

    This can hopefully be an easier example for you, and it's also 3D like you asked for.

    Sorry I didn't modify your code to 3D (which you could probably relate to better) but I'm just starting to learn them myself...

    Code:
    int loop, loop2;
    int x = 5;
    int y = 2;
    int z = 3;
    
    // create first subscript
    long ***group_total;
    group_total = malloc (x * sizeof (long **));
    
    if (!group_total)
     {
      printf ("\n\nError!  Not enough memory!\n\n");
      exit (1);
     }
    
    //create second subscript
    for (loop = 0; loop < x; loop++)
     {
      group_total[loop] = malloc (y * sizeof (long *));
    
      if (!group_total[loop])
       {
        printf ("\n\nError!  Not enough memory!\n\n");
        exit (1)
       }
    
      //create third subscript
      for (loop2 = 0; loop2 < y; loop2++)
       {
        group_total[loop][loop2] = malloc (z * sizeof (long));
    
        if (!group_total[loop][loop2])
         {
          printf ("\n\nError!  Not enough memory!\n\n");
          exit (1)
         }
       }
     }
    
    for (loop = 0; loop < x; loop++)
     {
      //free third malloc
      for (loop2 = 0; loop2 < y; loop2++)
        free (group_total[loop][loop2]);
    
      //free second malloc
      free (group_total[loop]);
     }
    
    //free first malloc
    free (group_total);

  5. #5
    Registered User Micko's Avatar
    Join Date
    Nov 2003
    Posts
    715
    Thanks Lionmane, however I was interested in solution that minimize number of malloc calls. Dave's link is very helpfull, somehow I missed that when searched the board.

    - Micko
    Gotta love the "please fix this for me, but I'm not going to tell you which functions we're allowed to use" posts.
    It's like teaching people to walk by first breaking their legs - muppet teachers! - Salem

  6. #6
    Registered User
    Join Date
    Jul 2005
    Posts
    7

    allocating 3d Matrix

    HI! i have designed a function to allocate a 3d matrix elements.

    the function is:
    Code:
    /* mem_node_matrix_3D {{{ */
    Node3D ***mem_node_matrix_3D(int m ,int n, int l )
    {
        int i,j,k;
        int dimension_2D, dimension_3D;
    
        Node3D *p;
        Node3D **q;
        Node3D ***r;
    
        dimension_2D = (m + 1) * (n + 1);
        dimension_3D = dimension_2D * (l + 1);
    
        r = (Node3D ***) malloc( (size_t) (m + 1) * sizeof(Node3D **));
        q = (Node3D **) malloc( (size_t) dimension_2D * sizeof(Node3D *));
        p = (Node3D *) malloc( (size_t) dimension_3D * sizeof(Node3D ));
    
        if(q == NULL) error_laplace_3D("mem_node_matrix : q no inicializado");
        if(p == NULL) error_laplace_3D("mem_node_matrix : p no inicializado");
        if(r == NULL) error_laplace_3D("mem_node_matrix : r no inicializado");
    
    
        for(i = 0; i <= m; i++)
        {
            r[i] = q;
            for (j = 0 ;j <= n; j++)
            {
                *q = p;
           for (k = 0; k <= l; k++)
                {
                    p->fixed = 0;
                    p->potential = 0.0;
                    p++;
                }
                q++;
            }
        }
    
        printf("lo q devuelve la asignacion de memoria = %p\n",r);
    
        return (r);
    }
    /* }}} */
    where node3d is a structure that contains:
    int fixed;
    double potential;

    ...but the function is easy generalizable to other structures or elemental data.

    The function works fine, i have solved calculus problems with it.

    ... but now the problem, how can i free the memory allocated??

    I use this code but i obtain a Segmentation Fault error:
    Code:
    /* free_net_3D {{{ */
    void free_net_3D()
    {
        int i,j;
        Node3D *p;
        Node3D **q;
    
    
        for( i = 0; i <= net3d.X; i++ )
        {
            q = net3d.nodes[i];
            for( j = 0; j <= net3d.Y ;j++ )
            {
                p = q[j];
                free(p);
            }
            free(q);
        }
    
        free(net3d.nodes);
        net3d.nodes = NULL;
    
        net3d.X = 0;
        net3d.Y = 0;
        net3d.Z = 0;
    }
    /* }}} */

    Someone can help me????? Thanks in advanced ....

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You shouldn't cast malloc(), see the FAQ. (If you get a warning, include <stdlib.h>.)

    What's the definition of Node3D?

    If you get a Seg fault, you probably haven't allocated the memory you're trying to access.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    Registered User
    Join Date
    Jul 2005
    Posts
    7
    Please, can u read my message another time?
    I say that the function works fine, the mem is allocating rightly, the problem is using the freeing function. the malloc don't give me problems, i can calculate values in the net without problems.

    If u read between lines u can see the node3d definition...

    And, why i can't cast malloc, i need a pointer to these structure.
    Where is that FAQ?

    Thanks

  9. #9
    Registered User
    Join Date
    Jul 2005
    Posts
    7
    Ok , i have read the FAQ, seems that is no problem casting malloc if i use stdlib.h, and i am using it.

  10. #10
    Registered User
    Join Date
    Jul 2005
    Location
    Transcarpathia
    Posts
    49
    casting void * is silly.
    C != C++

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Well you only have 3 malloc calls, so you only need 3 free calls.
    It looks like you allocate enough memory for each 'dimension', then split it up manually in the loops.

    In which case, I think it's something like
    free( net3d.nodes[0][0] ); // should be the same as p in the allocator
    free( net3d.nodes[0] ); // same as q
    free( net3d.nodes );

    > void free_net_3D()
    The thing you want to free should be a parameter, not a global variable.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    Jul 2005
    Posts
    7
    But i have a global variable, i am doing a library for general proposes. Why i canīt use a global variable??

    I have the same code for 2D nodes matrix , i use a global variable, not static, and code works fine, .... If u want to see the code say me , thanks

  13. #13
    Registered User
    Join Date
    Jul 2005
    Posts
    7
    Quote Originally Posted by valenok
    casting void * is silly.
    C != C++
    casting void * isnīt silly , are old manners

  14. #14
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >casting void * isnīt silly
    In C it is. You're making maintenance harder and actively trying to hide bugs. How is that not silly?

    >are old manners
    Casting malloc hasn't been a good practice for a LONG time. So how long have you been programming in C?
    My best code is written with the delete key.

  15. #15
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > But i have a global variable, i am doing a library for general proposes. Why i canīt use a global variable??
    Because I consider
    Code:
    Node3D ***foo = mem_node_matrix_3D(2,3,4);
    // some stuff
    free_net_3D ( foo );
    To be far more flexible than.

    Code:
    Node3D ***magicGlobalVariable;
    
    void somefunc ( void ) {
      magicGlobalVariable = mem_node_matrix_3D(2,3,4);
      // some stuff
      free_net_3D ( );
    }
    I mean what happens when you need two of these objects?

    Besides, did you fix the segfault or not?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  2. Replies: 4
    Last Post: 11-02-2006, 11:41 AM
  3. Dynamic allocation of an array of strings
    By earth_angel in forum C Programming
    Replies: 3
    Last Post: 06-24-2005, 09:40 AM
  4. Hi, could someone help me with arrays?
    By goodn in forum C Programming
    Replies: 20
    Last Post: 10-18-2001, 09:48 AM
  5. dynamic allocation question
    By vale in forum C++ Programming
    Replies: 1
    Last Post: 08-26-2001, 04:23 PM