Thread: FAQ: Casting malloc?

  1. #16
    Blank
    Join Date
    Aug 2001
    Posts
    1,034
    Maybe, but if your that asleep maybe you would cast
    to the wrong type.

  2. #17
    Registered User
    Join Date
    Sep 2002
    Posts
    272
    If you're so asleep as to cast it to the wrong type then you're not aware of the type(amount) of memory you're allocating, so cast or no cast you're in trouble.
    Joe

  3. #18
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Originally posted by JoeSixpack
    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).
    malloc returns a pointer to some memory (if successful). How you choose to interpret this memory depends on the type of the pointer to which this value is assigned. The cast is irrelevant if you are using a construct like the following, which will always be correct.
    Code:
    mytype *t = malloc(10 * sizeof(*t));
    This way I can be completely asleep and not even care about the type of *t or how big it might be -- the compiler will handle that and at runtime it will kindly ask for room for 10. So why bother getting a warning about an incorrect cast -- since that is the only thing that would be incorrect if you used N * sizeof(*t) -- and then spending your time maintaining this unnecessary code? It is already correct without it.

  4. #19
    Registered User
    Join Date
    Sep 2002
    Posts
    272
    The cast is irrelevant if you are using a construct like the following, which will always be correct.
    code:--------------------------------------------------------------------------------mytype *t = malloc(10 * sizeof(*t));--------------------------------------------------------------------------------
    .
    This is correct (in theory, if not syntax), but doesn't properly address my point. If you want x mytypes, then you can ask for x mytypes and be certain that you're getting x mtypes (as oposed to x t's) and that you're assigning the address the correct type of pointer if a cast is used. The type information may not always be present in the expression using your method. Further on in your code you may have -

    t = malloc(20 * sizeof(t));

    Did you really want 20 t's? t is just a variable name. It is possible that due to an oversight you believed t was of type mytype2 and not mytype. If you want 20 mytype2's, you can guarantee that if there's room enough and t is a pointer to mytype2 then this'll get them if it doesn't issue an error or warning -

    t = (mytype2*)malloc(20 * sizeof(mytype2));
    Joe

  5. #20
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Originally posted by JoeSixpack
    This is correct (in theory, if not syntax), but doesn't properly address my point. If you want x mytypes, then you can ask for x mytypes and be certain that you're getting x mtypes (as oposed to x t's)
    I would prefer to ask for space for objects of the same type as the pointer, and not have to worry about what the type is specifically.
    [...] and that you're assigning the address the correct type of pointer if a cast is used.
    So the following is "fixed" with the cast?
    Code:
    int *t = (int*)malloc(N * sizeof(int*));
    Once I replace sizeof(type) with sizeof(object of same type as pointer), then I don't "need" the cast that helps hide the above bug.
    Code:
    anytype *t = malloc(N * sizeof(*t));
    Continuing...
    [...] The type information may not always be present in the expression using your method.
    How does a variable lose its type?
    [...] Further on in your code you may have -

    t = malloc(20 * sizeof(t));

    Did you really want 20 t's?
    Actually, no. I didn't want space for 20 pointers; I wanted space for 20 objects.
    [...] t is just a variable name.
    No, t is a pointer of some type. And sizeof(*t) is -- ahem -- the size of the object to which it points, whatever type that may be.
    [...] It is possible that due to an oversight you believed t was of type mytype2 and not mytype.
    Actually I didn't care what the underlying type of t was because it no longer mattered. Whatever type it is, I'm asking for space for 20 of them. Because I didn't ask for space for a number of a presumed type -- I instead asked for space for a number of objects of the same type as the pointer -- this problem does not arise.
    If you want 20 mytype2's, you can guarantee that if there's room enough and t is a pointer to mytype2 then this'll get them if it doesn't issue an error or warning -

    t = (mytype2*)malloc(20 * sizeof(mytype2));
    Then you change t to anothertype and you have two more places to edit. I don't.

    I'm sorry. I've been down this road and back again several times. I have yet to see any justifyable advantage to casting. The only thing mentioned lately is for use with pre-ANSI compilers. Frankly I'd rather have the warnings pop up to let me know that I'm using an ancient compiler.

  6. #21
    Registered User
    Join Date
    Sep 2002
    Posts
    272
    I would prefer to ask for space for objects of the same type as the pointer, and not have to worry about what the type is specifically.
    Yeah, what the hell does it matter what you actually need?

    Once I replace sizeof(type) with sizeof(object of same type as pointer), then I don't "need" the cast that helps hide the above bug.
    But once again you're explicitly including the type in the expression. Do you declare a new pointer everytime you need some memory? If not how are you sure you've always got the correct type?

    How does a variable lose its type?
    Where did I say the variable loses its type?

    int i = 0;
    //some code
    i=10;

    what is i?

    It hasn't lost it's type. But the programmer is using a variable called i without explicitly using the type.

    Actually, no. I didn't want space for 20 pointers; I wanted space for 20 objects.
    This is true.

    No, t is a pointer of some type. And sizeof(*t) is -- ahem -- the size of the object to which it points, whatever type that may be.
    and this. I'm sorry.

    Actually I didn't care what the underlying type of t was because it no longer mattered. Whatever type it is, I'm asking for space for 20 of them. Because I didn't ask for space for a number of a presumed type -- I instead asked for space for a number of objects of the same type as the pointer -- this problem does not arise.
    WTF?? Of course you care what the underlying type is. If you want space for 20 int's, you want space for 20 int's. I can't see how what you've described could be anymore ass-backwards. Let's take some pointer type and hope the data fits.

    Then you change t to anothertype and you have two more places to edit. I don't.
    How? You've got at least one place to edit by changing your type somewhere. I'd only have one if I used a macro.
    Joe

  7. #22
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Regarding the usage of malloc, I prefer:

    TYPE *ptr;

    ptr = malloc( sizeof( TYPE ) * NUMBER_TO_ALLOCATE );

    There is no benefit I can see to ever casting, unless you are implicitly converting from one type to another. In malloc's case, there is no reason to ever cast that I can envision. The return type of malloc is to a continuous block of N bytes where N is:

    sizeof( TYPE ) * NUMBER_TO_ALLOCATE

    As such, it really doesn't matter what it's cast into, the cast is a moot point. Once a pointer is pointing at some block of memory, it could care less what type it was cast to when it was originally set to the address.

    Setting a pointer to point to an address does not change its type. As such, there is nothing that casting pointers from one type to the next provides, other than preventing your compiler from yelling at you. Example:

    char *c;
    int *i;
    float *f;

    f = (float*) i = (int*) c;

    This will (I believe, haven't bothered trying it) prevent your compiler from *****ing at you, but the end result is irrelevent.

    In the end, they all point to the same spot in memory, and in the end, when you increment any of them, they only increment by N bytes, where N is the size of each variable.

    So the end result is, it doesn't matter what you cast a pointer to, it will still be its own type, and nothing you can do will change that, unless you implicitly force cast it in incrementation:

    ((float*)c)++;

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

  8. #23
    Registered User
    Join Date
    Sep 2002
    Posts
    272
    As such, it really doesn't matter what it's cast into, the cast is a moot point.
    The cast (if used) is you telling the compiler that this is what you meant.

    Setting a pointer to point to an address does not change its type
    No, it's not meant to. It's so the compiler can give an error/warning. If you assign a block of memory to a different type of pointer than you had intended it may not have the desired affect.

    The problem isn't with the allocated memory, as casting isn't going to help if you balls up here. But with how this memory is manipulated.

    Once a pointer is pointing at some block of memory, it could care less what type it was cast to when it was originally set to the address.
    Exactly, but if you want a block of memory that can be manipulated in 1 byte regions, but allocate it to a pointer that increments/decrements in 4 byte regions then the pointer isn't going to care that you've made a mistake. However, casting the return value of malloc allows your compiler to provide a warning to this affect.

    In the end, they all point to the same spot in memory, and in the end, when you increment any of them, they only increment by N bytes, where N is the size of each variable.
    If you want a block of memory that you can manipluate in N-1 byte sections then either you're going to have to ensure that the address is assigned to a pointer that can increment by N-1 bytes (which you can be sure of if you cast), or by casting the pointer each time it's used (in which case why are you using the wrong type in the first place).

    So the end result is, it doesn't matter what you cast a pointer to, it will still be its own type, and nothing you can do will change that, unless you implicitly force cast it in incrementation
    The point in casting in this instance isn't to force the pointer to be something it isn't; but to enable the compiler to provide an error/warning.

    An example -

    Code:
    #include<stdlib.h>
    
    int main(void)
    {
    
    	char *c;
    	double *d;
    
    	//lots of code
    
    	//Lets say I want 20 integers
    
    	//this is wrong because I've
    	//assigned it to a character pointer
    	//even though I have the correct amount
    	//of memory
    	c = malloc(20*sizeof(int));
    
    	//this is wrong because I've
    	//made an error in assuming that
    	//d is a pointer to an integer
    	d = malloc(20*sizeof(*d));
    
    
    	//A cast indicating my intentions 
    	//on either of the previous 2 would 
    	//have brought the error to my attention
    	//with a compiler error/warning
    	//As they stand this program is
    	//buggy as hell
    
    
    
    	return(0);
    }
    Joe

  9. #24
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Originally posted by JoeSixpack
    Yeah, what the hell does it matter what you actually need?
    ???
    Originally posted by JoeSixpack
    But once again you're explicitly including the type in the expression. Do you declare a new pointer everytime you need some memory?
    Uh, no. The type is implicity present in the pointer variable. (Or do you see an explicit type as the operand of my sizeof?) And no.
    Originally posted by JoeSixpack
    If not how are you sure you've always got the correct type?
    *t has a type.
    Originally posted by JoeSixpack
    Where did I say the variable loses its type?
    Originally posted by JoeSixpack
    The type information may not always be present in the expression using your method.
    ...as previously quoted.
    Originally posted by JoeSixpack
    WTF?? Of course you care what the underlying type is. If you want space for 20 int's, you want space for 20 int's. I can't see how what you've described could be anymore ass-backwards. Let's take some pointer type and hope the data fits.
    Originally posted by Dave_Sinkula
    Then you change t to anothertype and you have two more places to edit. I don't.
    How? You've got at least one place to edit by changing your type somewhere. I'd only have one if I used a macro.
    The other two places being the cast and the operand to sizeof. I'd have only the pointer declaration (even if I didn't use a macro): the pointer variable declaration.

    If t is an int pointer, then *t is an int. And if t is a pointer to some other type, then *t is whatever type that is. Or is that ass-backwards?

  10. #25
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Originally posted by JoeSixpack
    The cast (if used) is you telling the compiler that this is what you meant.
    You're missing the point. The compiler doesn't CARE what you cast to. It has no effect. There is no point what so ever in casting malloc! It provides NOTHING to your code. It is worthless. It doesn't MATTER what you cast to, because you are casting a VOID POINTER. Void pointers, as far as your compiler is concerned, can go to ANYTHING, and there is absolutely no point what so ever in casting the return.

    You're just asking your compiler to yell at you by possibly casting it to the wrong type. There is no benifit what so ever in casting a void pointer. Period. Ever. End of story.





    Originally posted by JoeSixpack

    No, it's not meant to. It's so the compiler can give an error/warning. If you assign a block of memory to a different type of pointer than you had intended it may not have the desired affect.
    We're talking about void pointers. There is no reason to ever cast a void pointer. Your compiler will not complain about it, because it is impossible to cast a void pointer to the wrong type. Ever.

    The only reason you could ever possible get this wrong is if you typed the single malloc line wrong:

    char * c = malloc( sizeof(float) * 100 );

    And even then, it still won't care. The only way it would care, would be if you cast it implicitly. Why on earth would you?

    char * c = (float*) malloc( sizeof( float ) * 100 );

    And that's absurd. Why on earth would you ever do that? There is no point in EVER casting void pointers. Period.

    Originally posted by JoeSixpack

    Exactly, but if you want a block of memory that can be manipulated in 1 byte regions, but allocate it to a pointer that increments/decrements in 4 byte regions then the pointer isn't going to care that you've made a mistake. However, casting the return value of malloc allows your compiler to provide a warning to this affect.
    Yes, but how in the hell would this ever happen? You would have to be incredibly stupid and drunk to have this happen. In this case, casting is not going to save you. If you are stupid enough to malloc this incorrectly in the first place, then the chances are you're going to have screwed up your cast anyway, so there again is no benifit.

    Your argument is absurd, as is your example. I cannot envision this ever possibly happening. By all means, feel free to cast, but there is absolutely no point in ever doing so. Your example is incredibly far fetched. You're basicly saying "Hey, forget that you just declared a variable, and pretend that you think it's some other type!"


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

  11. #26
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    There is one interesting point here that is almost illustrated.
    Originally posted by JoeSixpack [and snippage by Dave_Sinkula]
    An example -

    Code:
    #include<stdlib.h>
    int main(void)
    {
    	double *d;
    
    	//lots of code
    
    	//Lets say I want 20 integers
    
    	//this is wrong because I've
    	//made an error in assuming that
    	//d is a pointer to an integer
    	d = malloc(20*sizeof(*d));
    
    	return(0);
    }
    I get no compiler warning when I try to assign a variable of one type the value of another type for which there is an implicit type conversion. Lint will pick this out, but the compiler (with the options I've selected) lets it fly. That is to say, the compiler issues no diagnostic for the following.
    Code:
    int x = 5.0;
    Hmmm. I still despise casts. When not used for an actual conversion (like truncation of an int to a char), they are simply lies. But this is an issue I will have to consider. (At least the memory allocation is correct, although it should be free'd so as not to be rude.)

  12. #27
    Registered User
    Join Date
    Sep 2002
    Posts
    272
    You're missing the point. The compiler doesn't CARE what you cast to. It has no effect. There is no point what so ever in casting malloc! It provides NOTHING to your code. It is worthless. It doesn't MATTER what you cast to, because you are casting a VOID POINTER. Void pointers, as far as your compiler is concerned, can go to ANYTHING, and there is absolutely no point what so ever in casting the return.
    This isn't what I'm talking about at all. As I'm getting tired of repeating myself I'll refer you to my example posted above.

    You're just asking your compiler to yell at you by possibly casting it to the wrong type. There is no benifit what so ever in casting a void pointer. Period. Ever. End of story.
    Ok, explain how there would be no benefit in casting in my example.

    Your compiler will not complain about it, because it is impossible to cast a void pointer to the wrong type. Ever.
    Where have I stated anything different? This is not what I'm talking about.

    Your argument is absurd, as is your example. I cannot envision this ever possibly happening.
    Hooray, at least I seem to have gotten through. It may be absurd, but my example shows a situation where casting would be beneficial.

    If you cannot show me how casting would not highlight the errors (and therefore help in the fixing of those errors) in my example posted above then my point stands no matter how absurd you believe it to be. End of story.
    Joe

  13. #28
    Registered User
    Join Date
    Dec 2001
    Posts
    88
    int* p;

    p=(char*)malloc(100);

    so what? Compiler says: failure!
    But what is the benefit?

    It's a false sense of security:
    p=(int*)malloc(100);

    The compiler don't say anything - but it's also wrong...
    What does it help?

    If you don't know which type p is, you are completly lost.

    I don't want to discuss such things. Go and read K&R. Do they cast?? Or look for other gurus! They will tell you all the same.

    The only reason why one casts a void* is to keep compability with C++, there is no other reason.
    Hope you don't mind my bad english, I'm Austrian!

  14. #29
    Registered User
    Join Date
    Sep 2002
    Posts
    272
    But what is the benefit?
    Yawn. The benefit is that if you use the cast to indicate you're expecting the block of memory to be pointed to by a character pointer and if you foolishly point something else at it the compiler will let you know. Is this really that hard to comprehend?

    It's a false sense of security:
    p=(int*)malloc(100);

    The compiler don't say anything - but it's also wrong...
    What does it help?
    It's not wrong for the reason posted above though. It's not supposed to help when you try and allocate the incorrect amount of memory. Does this mean it's not useful in your first example?

    If you don't know which type p is, you are completly lost.
    Why bother having the compiler do any type checking at all then?

    I don't want to discuss such things. Go and read K&R. Do they cast?? Or look for other gurus! They will tell you all the same.
    Can you not tell me why? I'm not necessarily stating that you should cast the return value of malloc. Just countering the point that it is of no benefit. Your last point is a non-argument.
    Joe

  15. #30
    Registered User The Dog's Avatar
    Join Date
    May 2002
    Location
    Cape Town
    Posts
    788
    Originally posted by JoeSixpack

    Yawn. The benefit is that if you use the cast to indicate you're expecting the block of memory to be pointed to by a character pointer and if you foolishly point something else at it the compiler will let you know. Is this really that hard to comprehend?
    I fully understand your point, but it just doesn't help to cast malloc(). Joe, if you really think that casting can help in a certain situation, then think about this :

    You're 500 lines into your program and you need to allocate some memory, here's what you see,
    Code:
    //..
    temp = malloc ( sizeof ( type ) * NUM_OF_ELEMENTS );
    //..
    You can't see the decalaration of temp but you know it's type. So if you happen to pass the wrong type to sizeof(), then what's the point in casting the return of malloc()?

    Yeah you could argue that you can just scroll up to temp's declaration, but then you'd never pass the wrong type to sizeof(), so what's your argument?

    You're f'ed both ways!
    Casting doesn't help, in any way, IMO.

    Is your compiler gonna stop you from doing this :
    Code:
    //..
    int *iPtr;
    iPtr = malloc ( sizeof ( char ) * NUM_OF_ELEMENTS);
    //..
    Nope, I didn't think so.

    Originally posted by JoeSixpack (Worded differently)

    Casting a malloc() return in C can only be beneficial when trying to assign mismatched pointers.
    But then you still have to check that the amount of memory that you're allocating is correct. So if you have to check both, why not leave the cast, and just check the size.

    Thus, less checking, less typing. So c'mon how can casting a malloc() return be beneficial?

    And the beat goes ooooooooon! Ladadadadee, Ladadadadaa.

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