Thread: FAQ: Casting malloc?

  1. #1
    Registered User
    Join Date
    Aug 2002
    Posts
    34

    FAQ: Casting malloc?

    Gday,

    Just wondering, i have read a fair bit that you shouldn't cast malloc and i am just wondering what casting actually is e.g

    from another post
    Code:
    example t=(char*)malloc(26 * sizeof(char));
    prelude said not to cast malloc,

    can someone explain what this casting is and how it has been done in this example. and what to do instead?

    Thanks

  2. #2
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    malloc returns a void pointer...what this means is that the return points to something, but that something could be more or less anything......so what you are doing above is giving a hint to the compiler that the data returned from malloc should be treated as a pointer to a char (or an array of chars).......

    in std C, there's no need to cast from malloc, but of you are compiling your code as C++, it will give an error without the cast being present.....this is due to C++ being more type sensitive (it has to be due to its ability to define custom types)

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    casting is where you (the programmer) decide that you know better than the compiler.

    So when you say this
    (char*)malloc(10)

    You're saying that you take whatever malloc returns, convert it to a char*, and assign that to the variable in question.

    This is all well and good if malloc is prototyped properly (by including stdlib.h), where it's defined as returning void*.

    The problem comes in when you fail to include stdlib.h, and the compiler initially assumes that malloc returns an int. The real problem is, you DONT get any warning from the compiler.

    You merrily then convert that int to a char* (via the cast). On machines where sizeof(char*) is different from sizeof(int), the code is seriously broken.

    Now if you just have
    char *var = malloc( 10 );
    And you miss out the include <stdlib.h>, you will get a warning from the compiler.

    http://www.eskimo.com/~scs/C-faq/s7.html

  4. #4
    Registered User
    Join Date
    Aug 2002
    Posts
    34

    Re: Casting malloc?

    so instead of this:
    Originally posted by Simon

    Code:
    t=(char*)malloc(26 * sizeof(char));
    which casts malloc as a char*,
    you would be better to do this:
    Code:
    t=malloc(26 * sizeof(char));
    ???

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > you would be better to do this:
    In C, yes

    But note Fordy's comments about C++

    But in C++, you should be using the new operator to get more memory, not malloc

  6. #6
    Registered User
    Join Date
    Aug 2002
    Posts
    34

    Talking

    Thanks Salem,

    Always Very Reliable.

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    I have a couple of comments. Let's start with this.
    Code:
    char *t=(char*)malloc(26 * sizeof(char));
    As has already been discussed, the cast is something to avoid in C. It is a holdover from the pre-ANSI C days.
    http://www.eskimo.com/~scs/C-faq/q7.7.html

    So then we have the following.
    Code:
    char *t = malloc(26 * sizeof(char));
    But it is useless to do sizeof(char) because it is always 1. So it could just as well be as follows.
    Code:
    char *t = malloc(26);
    But I prefer the following instead.
    Code:
    char *t = malloc(26 * sizeof(*t));
    Then if I need to change t to some other type, the code only needs to be changed in one spot.
    Code:
    long *t = malloc(26 * sizeof(*t));
    Dwelling on this a little, I find that even sizeof(int) stands out as code to avoid. If you use sizeof on the object itself, you always get its correct size. If you use sizeof on the presumed type of an object, you will get the size of a presumed type -- which may or may not be the size of the object.

    This may seem trivial for small amounts of code. But when project get bigger and changes are in multiple modules it can get confusing. I guess I just find it better to avoid the middleman and always be safe.

  8. #8
    Registered User
    Join Date
    Sep 2002
    Posts
    272
    Whilst I agree with what has been posted, would I be correct in assuming that when/if C99 is widely supported, the benefit of not casting malloc for the reasons mentioned will be nullified because the standard forbids implicit function declaration? So that for normal coding, if you want the compiler to help you it may be preferable to type cast?
    Joe

  9. #9
    Visionary Philosopher Sayeh's Avatar
    Join Date
    Aug 2002
    Posts
    212
    In the first place, there is nothing wrong with using type coercion. newbies call this 'casting'. All it does is help the compiler convert a returned type from one type to another type. And in fact, is necessary for code portability to older compilers and on some platforms.

    As for lauding the C99 standard, be careful. Many things about the C99 standard are actually incorrect because they have been instituted by persons with too little knowledge and history in programming. In many cases obfuscating what was once obvious into something abstract.

    When you say:

    Code:
    t = (int*) malloc(sizeof(int) * 200);
    You are _not_ coercing a function, you are coercing its result. Once again, this is merely to get your logic (for whatever reason you want an int pointer) past the compiler's syntactics.

    You must be smarter than your tools.
    It is not the spoon that bends, it is you who bends around the spoon.

  10. #10
    Registered User
    Join Date
    Oct 2002
    Posts
    2
    Well a lot has been said on this topic instead of repeating these things i would like to tell something.

    No reply has yet covered why we do type casting? what is the problem;

    Lets say u allocate the following memory:

    ---------------------------------------------
    code follows
    ----------------------------------------------
    char *t;

    t=malloc(10*sizeof(char));

    -----------------------------------------------
    Now u have to operate the memory provided to u one by one. So the compiler must know the size of one unit of data. Now the default value returned by malloc is void , though most of the compilers will adjust for it by looking at the LHS data type,but even then to avoid any undesireable and unintended affects we should tell the compiler about the data type. As malloc returns void it can be typecasted any data type. now when u will execute the following code
    -------------------------
    t++;
    ----------------------
    the no of unit data types to skip to go to the next unit data type will depend upon what type of value is *t holding if we typecast the reurned data type by malloc to unsigned * it will skip 4 of if we typecast it to char * it will skip none;
    Last edited by nsbuttar; 10-04-2002 at 01:51 PM.

  11. #11
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Originally posted by nsbuttar
    the no of unit data types to skip to go to the next unit data type will depend upon what type of value is *t
    Very true.
    Originally posted by nsbuttar
    [...] holding if we typecast the reurned data type by malloc to unsigned * it will skip 4 of if we typecast it to char * it will skip none;
    The cast of the return value of malloc is not at all relevant to incrementing a pointer. It is the pointer type that tells the compiler how many bytes to increment the pointer, not the manner in which the pointer was assigned its current value.
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #define WYSIWYG(x)   #x, (x)
    int main(void)
    {
       char *t = (int*)malloc(15), *copy = t;
       if(t)
       {
          printf("%s = %p\n", WYSIWYG(t));
          ++t;
          printf("%s = %p\n", WYSIWYG(t));
          free(copy);
       }
       return(0);
    }
    /* my output
    t = 007A305C
    t = 007A305D
    */
    The pointer advanced neither none nor 4. It advanced the expected 1. Let's try that the other way around. I'd expect my pointer to advance sizeof(int), which is 4 for the following.
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #define WYSIWYG(x)   #x, (x)
    int main(void)
    {
       int *t = (char*)malloc(15), *copy = t;
       if(t)
       {
          printf("%s = %p\n", WYSIWYG(t));
          ++t;
          printf("%s = %p\n", WYSIWYG(t));
          free(copy);
       }
       return(0);
    }
    /* my output
    t = 007A305C
    t = 007A3060
    */
    Yup. I see casting the return value of malloc as all cost and no benefit.

  12. #12
    Visionary Philosopher Sayeh's Avatar
    Join Date
    Aug 2002
    Posts
    212
    nsbuttar stated:

    No reply has yet covered why we do type casting? what is the problem;
    In fact, I did provide an answer to this question:

    All it does is help the compiler convert a returned type from one type to another type
    ----

    I will say it simpler so you understand. "type coercion" or "casting" is used solely to make the compiler see two different types of variable as the same thing, so long as they are the same size.

    if you don't use coercion, you will get a 'type mismatch' warning/error, depending on the compiler.

    This is a syntactic/grammar issue, not a C-language logic issue.
    It is not the spoon that bends, it is you who bends around the spoon.

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    To make it simple to understand...

    Think of a void pointer as a union that has reference to every single type of data you could ever possibly think of. Hehe.

    Quzah.
    Hope is the first step on the road to disappointment.

  14. #14
    Blank
    Join Date
    Aug 2001
    Posts
    1,034
    Well look at this way. When you want to find the sin of int x do
    you do sin(x) or sin((double)x). Both are correct and both
    coerse the type. Use whatever
    you think looks best. Not including stdlib.h is kind of non-issue.
    Anyone using a c compiler without turning on warnings
    for this should not be programming.

  15. #15
    Registered User
    Join Date
    Sep 2002
    Posts
    272
    As for lauding the C99 standard, be careful
    I wasn't lauding it, just pointing out its implications.

    Yup. I see casting the return value of malloc as all cost and no benefit.
    A possible benefit of casting would be that you ensure that you are using the correct pointer type. If you want a block of ints, casting the return type ensures that you can only assign the memory location to an int pointer (or that you should at least get some kind of warning, depending on your compiler).
    Joe

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Wiki FAQ
    By dwks in forum A Brief History of Cprogramming.com
    Replies: 192
    Last Post: 04-29-2008, 01:17 PM
  2. malloc, calloc from the FAQ
    By salvadoravi in forum C Programming
    Replies: 10
    Last Post: 01-21-2008, 03:29 AM
  3. malloc casting - quote from the FAQ
    By salvadoravi in forum C Programming
    Replies: 16
    Last Post: 12-17-2007, 06:24 PM
  4. FAQ: Difference between C and C++ style casting
    By Queatrix in forum FAQ Board
    Replies: 1
    Last Post: 12-23-2006, 12:09 PM
  5. Casting malloc?
    By Simon in forum C Programming
    Replies: 44
    Last Post: 10-08-2002, 02:25 AM