Thread: function reveives a 2-d array as parameter

  1. #16
    Registered User
    Join Date
    May 2007
    Location
    China
    Posts
    37

    thank all!

    my problem solved, thanks to all.
    according to matsp and Salem's method, i write two different version codes,
    (they are 3d arrays)and they work fine for me , post it, hoping helpful
    in the first version , i've a question about free();
    version1:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void fun(int ***arr);
    int ***send(void);
    
    int main(void)
    { 
        int ***ptr;
        ptr = send();   
        fun(ptr);
        getchar();
    return 0;
    }
    
     void fun(int ***arr)
     {
       int i;
       for(i=0; i<10; i++)
       {
         printf("%d\n", arr[0][0][i]); // print just 10 elements
       }
      free(arr); // should i use free() 3 times as i used 3malloc for arr?
                      //  or 1 free() is enough? }
      
    int ***send(void)
    {
        int i;
        int j;
        int k;
        int ***twodarray;
        
        for(i=0; i<10; i++)
          twodarray = (int***)malloc(10*sizeof(int));
       
        for(i=0; i<10; i++)
          twodarray[i] = (int**)malloc(10*sizeof(int));
        
        for(i=0; i<10; i++)
          for(j=0; j<10; j++)
              twodarray[i][j] = (int*)malloc(10*sizeof(int));
              
        for(i=0; i<10; i++)
          for(j=0; j<10; j++)
            for(k=0; k<10; k++)
              twodarray[i][j][k] = 0;
              
        return twodarray;  
    }
    version2:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void fun(int (*arr)[10][10]);
    int (*send(void))[10][10];
    
    int main(void)
    {
        int (*ptr)[10][10]; //"this is a pointer to an array of ten elements"
        ptr = send();       // ptr[10][10] "10 pointers to integers"
        fun(ptr);
        getchar();
    return 0;
    }
    
    void fun(int (*arr)[10][10])
     {
       int i;
       for(i=0; i<10; i++)
       {
         printf("%d\n", arr[0][0][i]); // print just 10 elements
       }
     }
      
    int (*send(void))[10][10]
    {
        int static twodarray[10][10][10] = {0};
        
        return twodarray;  
    }

  2. #17
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Each call to alloc has to have a corresponding call to free.

    You need to essentially do the REVERSE of your allocation, so you need to loop through your hundred elements and free them, then the 10 array pointers, then the base pointer [***arr] that you allocated at the beginning.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #18
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    > for(i=0; i<10; i++)
    > twodarray = (int***)malloc(10*sizeof(int));
    1. You only need one of these, not 10. 9 of them are lost.
    2. Don't cast the result of malloc in C
    3. The sizeof is wrong, it should be sizeof(int**)
    The same goes for the next malloc, which should be sizeof(int*)

    In general, you should use this form
    p = malloc ( numRequired * sizeof *p );
    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.

  4. #19
    Registered User
    Join Date
    May 2007
    Location
    China
    Posts
    37
    I made a little change...thanks

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void fun(int ***arr);
    int ***send(void);
    
    int main(void)
    { 
        int ***ptr;
        ptr = send();   
        fun(ptr);
        getchar();
    return 0;
    }
    
     void fun(int ***arr)
     {
       int i;
       int j;
       int k;
    
       for(i=0; i<10; i++)
         printf("&#37;d\n", arr[0][0][i]); // print just 10 elements
       
       for(i=0; i<10; i++)
          for(j=0; j<10; j++)
              free(arr[i][j]);
    
       for(i=0; i<10; i++)
          free(arr[i]); 
    
       free(arr);
     }
      
    int ***send(void)
    {
        int i;
        int j;
        int k;
        int ***twodarray;
        
        twodarray = (int***)malloc(10*sizeof(***twodarray)); // i cast malloc cause i edit the file in c++ enviorment.
       
        for(i=0; i<10; i++)
          twodarray[i] = (int**)malloc(10*sizeof(**twodarray));
        
        for(i=0; i<10; i++)
          for(j=0; j<10; j++)
              twodarray[i][j] = (int*)malloc(10*sizeof(*twodarray));
              
        for(i=0; i<10; i++)
          for(j=0; j<10; j++)
            for(k=0; k<10; k++)
              twodarray[i][j][k] = 0;
              
        return twodarray;  
    }

  5. #20
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    > i cast malloc cause i edit the file in c++ enviorment.
    So rename your prog.cpp to be prog.c

    Also, you've added ONE too many *'s to the sizeof expressions being used in the malloc calls.
    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.

  6. #21
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    > In general, you should use this form
    > p = malloc ( numRequired * sizeof *p );

    In case numRequired is a general expression, it's a little safer to put the sizeof on the left, like this:
    Code:
    p = malloc(sizeof(*p) * numRequired);
    since the argument to malloc() should be calculated as type size_t and this is more likely to happen without explicit casts if sizeof(*p) is on the left. For example, on a 64-bit platform where size_t is 64 bits and int is 32 bits,
    Code:
    p = malloc(sizeof(*p) * 0x10000U * 0x10000U);
    works properly, but
    Code:
    p = malloc(0x10000U * 0x10000U * sizeof(*p));
    doesn't. It doesn't always eliminate the need for a cast, though, since for example if numRequired was a sum instead of a product, one would have to write something like
    Code:
    p = malloc(sizeof(*p) * ((size_t)num1 + num2));
    but it eliminates some of them. This will matter more in 5 or 10 years when everyone is on a 64-bit platform and it's commonplace to allocate arrays > 2^32 elements.

  7. #22
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    I thought we discussed that very point in another thread?
    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.

  8. #23
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Quote Originally Posted by Salem View Post
    I thought we discussed that very point in another thread?
    You gave an example involving the product of two shorts, which had values which would have caused overflow, had the product been computed using short arithmetic, which is what you were assuming. However, by the integral promotion rules, the two shorts were actually being up-promoted to ints _before_ the multiplication, so there was no overflow. But the up-promotion doesn't go any bigger than int, so if you consider the product of two ints instead, where the product is too big for an int, it doesn't help anymore.

    Edit:
    Code:
    #include <stdio.h>
    
    int main(void) {
      /* prints the correct value thanks to integral promotion */
      printf("product of unsigned shorts: &#37;u\n", (unsigned short)0x100 * (unsigned short)0x100);
      /* prints the wrong value, even though GCC's 64-bit unsigned long long could hold the result */
      printf("product of unsigned ints: %llu\n", (unsigned long long)(0x10000U * 0x10000U));
      return 0;
    }
    Output on a 32-bit box:

    product of unsigned shorts: 65536
    product of unsigned ints: 0

    Original thread: http://cboard.cprogramming.com/showthread.php?t=95615
    Last edited by robatino; 12-04-2007 at 02:07 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. In over my head
    By Shelnutt2 in forum C Programming
    Replies: 1
    Last Post: 07-08-2008, 06:54 PM
  2. Including lib in a lib
    By bibiteinfo in forum C++ Programming
    Replies: 0
    Last Post: 02-07-2006, 02:28 PM
  3. Please Help - Problem with Compilers
    By toonlover in forum C++ Programming
    Replies: 5
    Last Post: 07-23-2005, 10:03 AM
  4. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM
  5. pointer to array as parameter to function
    By Jurgen in forum C++ Programming
    Replies: 1
    Last Post: 05-20-2004, 02:51 PM