Find the answer to your Linux question:
Results 1 to 5 of 5
when i allocate memory for a pointer with malloc() function, it is necessary to do cast on return of malloc? With other words the allocation must be implemented as: int ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jun 2010
    Posts
    24

    Using malloc() function


    when i allocate memory for a pointer with malloc() function, it is necessary to do cast on return of malloc? With other words the allocation must be implemented as:

    int *a;
    a=(int *)malloc( 8 );

    or it can be implemented without casting as:

    int *a;
    a=malloc( 8 ) ; ?

    which are the possible errors in second situation ?

    Also for a multi-dim array the allocation with cast become
    as? :

    int ***a;
    a=(int ***)malloc(n*sizeof(int **));

    for(k=0;k<n;k++)
    a[k]=(int **)malloc(n*sizeof(int *));

    for(k=0;k<n;k++)
    for(l=0;l<n;l++)
    a[k][l]=(int *)malloc(n*sizeof(int ));

  2. #2
    Linux Newbie
    Join Date
    Mar 2010
    Posts
    152
    Quote Originally Posted by pankos View Post
    when i allocate memory for a pointer with malloc() function, it is necessary to do cast on return of malloc?
    In C, no - in C++, yes.


    Quote Originally Posted by pankos View Post
    which are the possible errors in second situation ?
    There are none, except if you later change the type of a, you'll have to change the type you cast malloc() to (well, you'll have to for C++, with C you could put up with a warning). Either way, if you've malloc()'d the correct amount of memory the only way casting to a different pointer type could hurt is if you're on some archaic architecture that uses pointers of a different size for data and function pointers - my bet is you're not doing that...

    I normally don't use a cast for malloc(), as I don't see that it provides any benefit.

    Quote Originally Posted by pankos View Post
    Also for a multi-dim array the allocation with cast become
    as? :

    int ***a;
    a=(int ***)malloc(n*sizeof(int **));

    for(k=0;k<n;k++)
    a[k]=(int **)malloc(n*sizeof(int *));

    for(k=0;k<n;k++)
    for(l=0;l<n;l++)
    a[k][l]=(int *)malloc(n*sizeof(int ));
    Yes, that looks right - so long as you want each of a[i][j][k] to end up being a pointer to an array of n int values, and you want each level of the array to be the same size (i.e. an array of n whatever's).

  3. #3
    Linux Enthusiast Bemk's Avatar
    Join Date
    Sep 2008
    Location
    Oosterhout-NB, Netherlands
    Posts
    525
    Quote Originally Posted by JohnGraham View Post
    In C, no - in C++, yes.
    In C++ it is indeed possible to use malloc, but in general what you want to do is to use the new keyword. It's implemented in the C++ language, and does the casting thing for you.
    There are none, except if you later change the type of a, you'll have to change the type you cast malloc() to (well, you'll have to for C++, with C you could put up with a warning). Either way, if you've malloc()'d the correct amount of memory the only way casting to a different pointer type could hurt is if you're on some archaic architecture that uses pointers of a different size for data and function pointers - my bet is you're not doing that...

    I normally don't use a cast for malloc(), as I don't see that it provides any benefit.
    I too rarely use a cast on the malloc output, and if all goes well, they shouldn't give an error, due to the simple fact that you're using a void pointer(yep, void pointers are loads of fun). If all goes well, you shouldn't even receive a warning.

    C only cares about type when dereferencing, otherwise, you can do the weirdest things with the pointer.

    Code:
    int ***a;
    a=(int ***)malloc(n*sizeof(int **));
    
    for(k=0;k<n;k++)
    a[k]=(int **)malloc(n*sizeof(int *));
    
    for(k=0;k<n;k++)
    for(l=0;l<n;l++)
    a[k][l]=(int *)malloc(n*sizeof(int ));
    The above code is an exact copy of the code in the first post.
    I do note one error here, and that is the fact that variable k isn't defined.
    In C you will have to define it in the function making your loop look like this:
    Code:
    int k;
    for (k = 0; k < n; k++)
    {/* Some code */}
    while C++ would allow you to do this:
    Code:
    for (int k = 0; k < n; k++)
    {/* Some code */}
    (Just because I don't know whether this is C or C++)

    Also note that this is going to allocate way too much memory:
    Code:
    int *a;
    a=(int *)malloc( 8 );
    Integers are 4 bytes in size, it's only the long long type and the long type that are actually 64-bits(8 bytes) in size, and even the long type can be 32-bits(4 bytes) on a 32-bits platform.

    I don't know the conventions for non-Intel compatible CPU's, but I don't think this will ever allocate the right amount of memory.

    Also note that the overhead for allocating memory is quite high. Not only does the integer take in more space than you'd think it would, but it would also go through a large amount of loops.

    Most memory allocators are optimised for larger chunks of memory, so just try to allocate memory in bulk instead of an integer at a time.
    Full time computer science student, spare time OS developer.
    @bemk92 on twitter.

  4. #4
    Linux Guru Cabhan's Avatar
    Join Date
    Jan 2005
    Location
    Seattle, WA, USA
    Posts
    3,252
    JohnGraham and Bemk gave some good answers to your questions. I'd like to address the last point that Bemk made.

    First of all, it is weird to see an int of size 8 bytes. So you may want to double-check that.

    But even if that is correct, this is not very good style. This means that on any system where an int is not 8 bytes, the program does not work very well. Either you will be allocating too much memory (not so horrible, I suppose), or you might not allocate enough (what if, in the future, ints require 12 bytes?).

    The correct way to implement this would be:
    Code:
    int *a;
    a = malloc(sizeof(int));
    sizeof(TYPE) always returns the number of bytes required to store a TYPE. So this will always be correct, no matter what system the program is compiled on.

  5. #5
    Linux Enthusiast Bemk's Avatar
    Join Date
    Sep 2008
    Location
    Oosterhout-NB, Netherlands
    Posts
    525
    Considering the overhead malloc produces, I don't think allocating 2 ints for 1 will cause a lot of issues. Malloc only starts to get somewhat efficient from the moment you start allocating 32 bytes or more. That's why I said it's best to malloc in bulk.

    I can try to explain why this is here, but I think that's a little of topic so I won't, and besides, Google can help you, if you really want to know.
    Full time computer science student, spare time OS developer.
    @bemk92 on twitter.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •