#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    3
    Rep Power
    0

    Dynamically allocating memory to by reference variables


    I need to dynamically assign memory to an array that is defined in a calling function. I am relatively new to C and would be very grateful for any advice about doing this.

    I have tried something like the following:

    Code:
    int main()
    {
        int n = 4;          // dimension of square matrix
        double** matrix;    // The matrix
        
        mk_matrix(&matrix, n);
        
        return 0;
    }
    
    void mk_matrix (double*** matrix, int n)
    {
        *matrix = (double*)malloc(n*sizeof(double));  // assign memory for rows
        for(i=0;i<n;i++)
        {
            *matrix[i]=(double*)malloc(n*sizeof(double)); // assign memory for columns
        }
    }
    Thank you in advance.
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,417
    Rep Power
    1871
    Observe.
    Code:
    int main()
    {
        int n = 4;          // dimension of square matrix
        double** matrix;    // The matrix
        
        mk_matrix(&matrix, n);
        
        return 0;
    }
    
    void mk_matrix (double*** matrix, int n)
    {
        //!! no cast of malloc, and different type in sizeof
        *matrix = malloc(n*sizeof(double*));  // assign memory for rows
        for(i=0;i<n;i++)
        {
            //!! () around the pointer, no cast of malloc
            (*matrix)[i]=malloc(n*sizeof(double)); // assign memory for columns
        }
        return;
    }
    You don't need to cast the return result of malloc in a C program. If you "need" a cast, you're doing something wrong - so wrong that just sweeping the problem under the carpet with a cast is the wrong thing to do.

    Comments on this post

    • farleytowers agrees
    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. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    3
    Rep Power
    0
    Thanks very much Salem. Much appreciated.
    Please could you also advise me how to then free the memory I have allocated?

    I've got:

    Code:
    void free_matrix(double*** matrix, int n) {
    
        for(i=0;i<n;i++) {
            free(*matrix[i]);
        }
        free(*matrix);
    }
    Thanks!
  6. #4
  7. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,417
    Rep Power
    1871
    Well you can get away with
    void free_matrix(double** matrix, int n)
    which simplifies things somewhat.

    >free(*matrix[i]);
    Recall the use of () in the malloc calls previously shown.

    Comments on this post

    • farleytowers agrees
    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. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    3
    Rep Power
    0
    Once again, thank you very much. This will be a very useful thing to be able to do.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2012
    Posts
    5
    Rep Power
    0
    Originally Posted by salem
    Observe.
    Code:
    int main()
    {
        int n = 4;          // dimension of square matrix
        double** matrix;    // The matrix
        
        mk_matrix(&matrix, n);
        
        return 0;
    }
    
    void mk_matrix (double*** matrix, int n)
    {
        //!! no cast of malloc, and different type in sizeof
        *matrix = malloc(n*sizeof(double*));  // assign memory for rows
        for(i=0;i<n;i++)
        {
            //!! () around the pointer, no cast of malloc
            (*matrix)[i]=malloc(n*sizeof(double)); // assign memory for columns
        }
        return;
    }
    You don't need to cast the return result of malloc in a C program. If you "need" a cast, you're doing something wrong - so wrong that just sweeping the problem under the carpet with a cast is the wrong thing to do.
    salem can you just explain why casting will be not needed , that means if i write the code like follows i think there is no error :

    void mk_matrix (double*** matrix, int n)
    {

    *matrix = (double **)(malloc(n*sizeof(double*));
    for(i=0;i<n;i++)
    {

    (*matrix)[i]=(double *)malloc(n*sizeof(double));
    }
  12. #7
  13. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,417
    Rep Power
    1871
    Try compiling it without the casts!

    If you get something like
    bar.c:4:13: warning: initialization makes pointer from integer without a cast
    Then you need to FIX your code by having #include <stdlib.h> at the top of the file.
    If your machine has larger pointers than integers, then having malloc declared as implicitly returning an int will lose information when you cast. Your resultant 'pointers' will be both non-null AND garbage.

    If you get something like
    bar.cpp:4:22: error: invalid conversion from ‘void*’ to ‘char*’
    Then you need to FIX your build system so that you compile your C code with a C compiler (and not a C++ compiler). This might mean for example renaming prog.cpp to be prog.c

    C and C++ are different languages, despite their recent common heritage.
    http://en.wikipedia.org/wiki/Compati..._C_and_C%2B%2B
    http://david.tribble.com/text/cdiffs.htm

    If you just casually compile your C code with a C++ compiler, you're just digging a big hole for yourself. Even if you don't care about the portability of the code, you'll be learning a lot of poor style which will cause you trouble when you come to use a real C compiler.
    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

IMN logo majestic logo threadwatch logo seochat tools logo