Thread: correct malloc use

  1. #1
    Registered User
    Join Date
    Nov 2004
    Posts
    55

    correct malloc use

    Hi all,
    I 'm having a bit of trouble understanding about the use of malloc for 1d and 2d arrays., and I would appreciate if someone could tell me what is correct. Lets say for 1d arrays, which is correct?

    vector = malloc(length*sizeof(vector));
    or
    vector = malloc(length*sizeof(*vector));
    and for 2d arrays:
    Code:
            matrix=malloc(rows*sizeof(matrix));
            for (i=0; i<columns; i++)
                    matrix[i]=malloc(columns*sizeof(matrix[i]));
    or
    Code:
            matrix=malloc(rows*sizeof(*matrix));
            for (i=0; i<columns; i++)
                    matrix[i]=malloc(columns*sizeof(*matrix[i]));
    I've tried both with gcc and all warnings/pedantic flags on, but both produce the same result (and no warnings) when I put some values in vector and array and then display them.

    I've also seen (assuming vector and matrix are unsigned integers
    Code:
    vector = malloc(length*sizeof(unsigned int*))
    and
    Code:
            matrix=malloc(rows*sizeof(unsigned int *));
            for (i=0; i<columns; i++)
                    matrix[i]=malloc(columns*sizeof(unsigned int));
    Ideally I'd like to avoid this in case I want to chenge the type of vector or matrix eg from float to double.

    Thank you
    Spiros
    Last edited by s_siouris; 05-28-2008 at 05:33 PM.

  2. #2
    ---
    Join Date
    May 2004
    Posts
    1,379
    what is vector?
    Code:
    const int SIZE = 10;
    int *vector;
    vector = malloc(SIZE*sizeof(int));
    I'm a little rusty myself, but I think that's correct.

  3. #3
    Registered User
    Join Date
    Nov 2004
    Posts
    55
    is it posible to use
    Code:
    const int SIZE = 10;
    int *vector;
    vector = malloc(SIZE*sizeof(vector));
    instead of
    Code:
    const int SIZE = 10;
    int *vector;
    vector = malloc(SIZE*sizeof(int));
    ?

  4. #4
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    In both cases, the second is correct (I'm assuming your declarations look something like int *vector and int **matrix). For your 1d array, since you're creating an array of (say) ints, you want to multiply the length by the size of an int, not a pointer. The 2d array is similar, only first you create an array of pointers to int, and then you create arrays of ints.
    Code:
    int *vector;
    sizeof vector;     /* size of a pointer to int, because that's what vector is */
    sizeof *vector;    /* size of an int, because that's what *vector is */
    int **matrix;
    sizeof matrix;     /* pointer to pointer to int */
    sizeof *matrix;    /* pointer to int */
    sizeof *matrix[i]; /* int; same thing as sizeof **matrix */
    I would not recommend using the type name with sizeof for the reason you mentioned. Why make it so you have to change the type twice? Less of a chance for a problem this way.

    Also, your 2d allocation is incorrect: If you allocate "rows * sizeof *matrix" then you should be doing "for(i = 0; i < rows; i++)", because that's how many you just allocated. If columns is greater than rows, your code writes outside of your allocated memory area. If it's smaller than rows, then you have uninitialized elements.

  5. #5
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> I've tried both with gcc and all warnings/pedantic flags on, but both produce the same result (and no warnings) when I put some values in vector and array and then display them.

    that's because sizeof( int ) == sizeof( int * ) on your system, naturally. for clarity, you should consider using that standard syntax for now, eg:

    Code:
    int * ptr = malloc( count * sizeof( int ) );
    
    int ** mtx = malloc( rows * sizeof( int * ) );
    for( int i = 0; i < rows; i++ )
          mtx[ i ] = malloc( columns * sizeof( int ) );
    Last edited by Sebastiani; 05-28-2008 at 05:52 PM.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  6. #6
    Registered User
    Join Date
    Nov 2004
    Posts
    55
    thanks cas, I'm now trying to get my head round what you've posted... pointers are a pain!

    As for the loop going over the columns, that's my mistake being too quick, it should go over "rows"

    Sebastiani, I have seen this way of allocating arrays that you've posted, and I could do it this way, but I think that if I write for example
    Code:
    sizeof(ptr)
    then I could change the type of ptr with one edit rather than two (one in declaration, and the other inside the sizeof). Is this way really non-standard syntax, because if it is then I'll try to get used to malloc as you suggested.

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    oh there's nothing wrong with that syntax, but if it's causing you so much confusion then why do it that way?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  8. #8
    Registered User
    Join Date
    Nov 2004
    Posts
    55
    I'm just trying to learn by trying different things. Unfortunately the books I've borrowed from my library are not very clear and therefore things in my head are not clear as well, but fortunately you guys are really helpful.

    thanks!

  9. #9
    Registered User
    Join Date
    Nov 2004
    Posts
    55
    I'm now having another problem with how much memory is allocated
    Code:
            double *vec_y;
            unsigned int nrows;
    
            vec_y = malloc(nrows*sizeof(*vec_y));
            for (i=0; i<nrows; i++) {
                    vec_y[i]=(double )i;
                    printf("\nvec_y[%i]=%f", i, vec_y[i]);
            }
    If I increase the for loop to eg 2*nrows like:
    Code:
            double *vec_y;
            unsigned int nrows;
    
            vec_y = malloc(nrows*sizeof(*vec_y));
            for (i=0; i<2*nrows; i++) {
                    vec_y[i]=(double )i;
                    printf("\nvec_y[%i]=%f", i, vec_y[i]);
            }
    then the printf statement just carries on printing i, and vec_y (being the same value as i) like I allocated 2*nrows*sizeof(*vec_y). This should not happen as I'm deliberately going out of the bounds of vec_y allocated by memory, yet I'm getting no errors during compilation or run time. Why does this happen?

  10. #10
    Registered User
    Join Date
    May 2008
    Posts
    87
    Code:
            double *vec_y;
            unsigned int nrows;
    
            vec_y = malloc(nrows*sizeof(*vec_y));
            for (i=0; i<2*nrows; i++) {
                    vec_y[i]=(double )i;
                    printf("\nvec_y[%i]=%f", i, vec_y[i]);
            }
    then the printf statement just carries on printing i, and vec_y (being the same value as i) like I allocated 2*nrows*sizeof(*vec_y). This should not happen as I'm deliberately going out of the bounds of vec_y allocated by memory, yet I'm getting no errors during compilation or run time. Why does this happen?
    First, I assume that nrows is initialized somewhere before it is used in the call to malloc()? Then, what you are seeing is that in fact, C does not perform any type of bounds checking. You can read beyond the end of an array, as well as assign values beyond its bounds. Powerful and dangerous if you aren't careful.

    Try this out this little bit of code:
    Code:
    char str[5] = "test";
    int i = 1;
    
    printf("str=%s\ti=%d\n", str, i);
    
    strcpy(str, "This is sure more than 5 characters!");
    
    printf("str=%s\ti=%d\n", str, i);
    Can you explain what happened?

  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
    > yet I'm getting no errors during compilation or run time. Why does this happen?
    Luck (for now).
    Call malloc again, and your luck might go down somewhat.
    Call free on the original pointer, that's a further decrease in luck.
    Sooner or later, you're looking down the barrel of a segmentation fault in an unrelated part of the program wondering "WTF!!?"

    Oh, and
    p = malloc( howmany * sizeof *p );
    ALWAYS works.
    Let the compiler do the work.
    No second looks back at how p was declared, or how many *s it has.
    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. malloc() resulting in a SegFault?!
    By cipher82 in forum C++ Programming
    Replies: 21
    Last Post: 09-18-2008, 11:24 AM
  2. Wierd Malloc Problem
    By mohankarthik in forum C Programming
    Replies: 11
    Last Post: 09-17-2008, 02:14 PM
  3. Malloc for extending the size....!
    By patil.vishwa in forum C Programming
    Replies: 5
    Last Post: 09-11-2008, 03:34 AM
  4. the basics of malloc
    By nakedBallerina in forum C Programming
    Replies: 21
    Last Post: 05-20-2008, 02:32 AM
  5. Random number + guessing game trouble
    By Ravens'sWrath in forum C Programming
    Replies: 16
    Last Post: 05-08-2007, 03:33 AM