View Full Version : FAQ: Casting malloc?
Simon
10-04-2002, 03:36 AM
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
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
Fordy
10-04-2002, 03:53 AM
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)
Salem
10-04-2002, 03:58 AM
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
Simon
10-04-2002, 04:06 AM
so instead of this:
Originally posted by Simon
t=(char*)malloc(26 * sizeof(char));
which casts malloc as a char*,
you would be better to do this:
t=malloc(26 * sizeof(char));
???
Salem
10-04-2002, 04:20 AM
> 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
Simon
10-04-2002, 04:34 AM
Thanks Salem,
Always Very Reliable.
Dave_Sinkula
10-04-2002, 09:24 AM
I have a couple of comments. Let's start with this.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 (http://)
So then we have the following.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.char *t = malloc(26);But I prefer the following instead.
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.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.
JoeSixpack
10-04-2002, 01:09 PM
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?
Sayeh
10-04-2002, 02:37 PM
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:
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.
nsbuttar
10-04-2002, 02:47 PM
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;
Dave_Sinkula
10-04-2002, 03:24 PM
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 *tVery 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.#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.#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.
Sayeh
10-04-2002, 03:48 PM
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.
quzah
10-04-2002, 04:09 PM
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.
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.
JoeSixpack
10-04-2002, 04:28 PM
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).
Maybe, but if your that asleep maybe you would cast
to the wrong type.
JoeSixpack
10-04-2002, 05:09 PM
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.
Dave_Sinkula
10-04-2002, 05:45 PM
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.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.
JoeSixpack
10-04-2002, 06:07 PM
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));
Dave_Sinkula
10-04-2002, 07:56 PM
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?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.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.
JoeSixpack
10-04-2002, 08:38 PM
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.
quzah
10-04-2002, 09:09 PM
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.
JoeSixpack
10-04-2002, 09:58 PM
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 -
#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);
}
Dave_Sinkula
10-04-2002, 10:07 PM
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?
quzah
10-04-2002, 10:22 PM
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.
Dave_Sinkula
10-05-2002, 12:12 AM
There is one interesting point here that is almost illustrated.
Originally posted by JoeSixpack [and snippage by Dave_Sinkula]
An example -
#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.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.)
JoeSixpack
10-05-2002, 05:18 AM
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.
Shade
10-05-2002, 05:37 AM
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.
JoeSixpack
10-05-2002, 05:47 AM
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.
The Dog
10-05-2002, 06:08 AM
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,
//..
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 :
//..
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.
JoeSixpack
10-05-2002, 09:39 AM
I fully understand your point, but it just doesn't help to cast malloc().
Then you don't fully understand my point.
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()?]
If you pass the wrong type to sizeof then you've allocated the incorrect amount of memory. So cast or no cast your in trouble (haven't we been here before). This has nothing to do with the point I'm making. If you know you want space for 20 int's how could you possibly pass the wrong type to sizeof()?
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?
My argument is nothing to do with looking at temps declaration. In fact my argument is based on the assumption that the coder has been sloppy and not looked at temps declaration. My argument is based on the coder knowing the amount of memory they need (as stated, casting is never going to help there), and what type of pointer they want to use to manoeuvre around this memory, but then selecting the wrong pointer.
Casting doesn't help, in any way, IMO.
Look at my example and explain from what I've written there how casting wouldn't help. How casting wouldn't help prevent you making an incorrect assumption about the pointer type you're using? It currently has two bugs based on my false assumptions. If I had included casts these bugs would have been highlighted. So how does this mean casting doesn't help in any way?
Prelude
10-05-2002, 10:04 AM
>Then you don't fully understand my point.
Allow me to take a stab at it. You are saying that the following code is wrong if I wanted to simulate an array of integers:
#include <stdlib.h>
/*
** my_header.h declares a to be a pointer to double
*/
#include "my_header.h"
int main ( void )
{
a = malloc ( 24 * sizeof *a );
return 0;
}
No warnings.
As it is the compiler implicitly converts the void pointer to a double pointer, the usage is correct, but not what you wanted. If, however, you had included a type cast to int * the compiler would likely give you a warning about incompatible types:
#include <stdlib.h>
/*
** my_header.h declares a to be a pointer to double
*/
#include "my_header.h"
int main ( void )
{
a = (int *)malloc ( 24 * sizeof *a );
return 0;
}
C:\C\C.c(9) : warning C4133: '=' : incompatible types - from 'int *' to 'double *'
This is a valid point, but so is the case for not using type casting. In the end, not using type casting is encouraged, but it is very largely a matter of style.
-Prelude
The Dog
10-05-2002, 11:28 AM
Joe, after all that, I don't think that you understand your point.
Your point should've been, "It helps not to be a sloppy programmer!".
Then everything would make sense!
Nuff said already!
Dave_Sinkula
10-05-2002, 01:02 PM
Originally posted by JoeSixpack
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.Please Read
*Errata for The C Programming Language, Second Edition (http://cm.bell-labs.com/cm/cs/cbook/2ediffs.html) #142
More Gurus
void main() and cast to malloc (http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=clcm-20000322-0020%40plethora.net&rnum=1&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DISO-8859-1%26q%3DDennis%2BRitchie%2Bmalloc%2Bcast%26sa%3DN% 26tab%3Dwg)
malloc question (http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=danpop.808513352%40rscernix&rnum=3&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DISO-8859-1%26q%3DDennis%2BRitchie%2Bmalloc%2Bcast%26sa%3DN% 26tab%3Dwg)
Pointer Casts (http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=35B8082D.D910E0F5%40mnsinc.com&rnum=4&prev=/groups%3Fhl%3Den%26lr%3D%26ie%3DISO-8859-1%26q%3DDennis%2BRitchie%2Bmalloc%2Bcast%26sa%3DN% 26tab%3Dwg)
JoeSixpack
10-05-2002, 03:07 PM
Your point should've been, "It helps not to be a sloppy programmer!".
Perhaps.
Originally posted by JoeSixpack
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.
This wasn't my quote. I was replying to some-one who posted it.
By all means, post keep posting links. It doesn't alter the fact that it can be beneficial to cast the return value of malloc. Also I stated this in the context of using a C99 conforming compiler (right back at the start of the thread). The reason often given (and is in a few of the links you've posted) for not casting malloc is the possible implicit prototype problem. This is no longer a problem if the compiler doesn't allow implicit prototypes.
Dave_Sinkula
10-05-2002, 07:22 PM
Originally posted by JoeSixpack
This wasn't my quote. I was replying to some-one who posted it.My apologies for the misquote.Originally posted by JoeSixpack
By all means, post keep posting links.Okay, one more. But I give up.
http://groups.yahoo.com/group/c-prog/message/12179
JoeSixpack
10-06-2002, 05:49 AM
That link is just rehashing what's already been posted here. It doesn't stop you making an error in the assumption as to what the pointer type is (you could falsely assume that ptr3 pointed to a foobar2).
foobar *ptr3;
/*lots of code*/
/*I now want 20 foobar2's
but make an error in my assumption
as to the type of pointer ptr3 is
and through my stupidity assume
that it has been declared to point
at a foobar2s*/
ptr3 = malloc (20*sizeof(*ptr3));
/*casting the return value of malloc
above would have explicitly told the compiler
what I was trying to do, and made it
scream at me. Therefore the method
used above is less robust*/
Also, the poster in your link complaining about all the cutting and pasting needed has presumably not heard of macros.
But I give up.
So do I :). Probably.
Shade
10-06-2002, 08:37 AM
It's funny to read...
I think noone will change their minds, so why discussing?
I (and as I see some others) keep doing it like the gurus, and you JoeSixpack keep casting.
I have learned that it is possible to program in a different style as the gurus, but I got to know, that it is somehow easier when you do what the gurus tell you :)
JoeSixpack
10-06-2002, 10:35 AM
I think noone will change their minds, so why discussing?
Change someones mind about what? I'm not trying to convince people that they should always cast the return value of malloc; just pointing out that it can be benefical in some situations. My example showed that by using casting two bugs could have been avoided. This wasn't my opinion. It was a fact.
I (and as I see some others) keep doing it like the gurus, and you JoeSixpack keep casting.
I have learned that it is possible to program in a different style as the gurus, but I got to know, that it is somehow easier when you do what the gurus tell you
That's a really intellitgent pov, Shade. As I said above I'm not trying to convince anyone that they should cast the return value of malloc. My initial post was a question, hoping to start a debate on the subject. Not provoke mindless guru fanboyism such as that demonstrated by you among others. If you'd like to point out why casting is a bad thing in the context of the example I gave, then I'm all ears (or eyes). Otherwise you're contributing nothing.
Sayeh
10-07-2002, 08:31 AM
I had to reinvolve myself with this-- this thread is an absurd example (yet again) of people becoming lost in the syntax issues of a language or a compiler, rather than being able to see beyond such things and get to the fascination of the logic.
Get's old, doesn't it.
-------------------------------------------------------------
To JoeSixPack:
I have yet to see any justifyable advantage to casting.
It has nothing to do with advantages or disadvantages. This is the wrong point of view. Stop thinking it is right or wrong. Type coercsion was developed for one reason and one reason only--
To resolve type mismatches at the preprocessor level. type coercion has nothing to do with execution.
---------------------------------------------------------------
To the rest of you:
If JoeSixPack wants to write all his code without ever using coercion-- fine. More power to this person.
We've listed what coercion/casting is for. It's a tool, nothing more. I prefer to utilize all my tools, rather than taking the extreme stance that 'tool x is good for nothing' or 'you should never use tool z'.
Keep on programming
JoeSixpack
10-07-2002, 12:41 PM
*Joe Sxpack bangs his head violently against the wall*
this thread is an absurd example (yet again) of people becoming lost in the syntax issues of a language or a compiler, rather than being able to see beyond such things and get to the fascination of the logic.
Actually, all this thread has seemed to demonstrate is peoples inability to read.
And that, is timeless. Nice misquote, btw.
master5001
10-08-2002, 01:11 AM
First off I would like to point out to everyone that says "don't type cast malloc()" that just because you don't need the type cast doesn't you shouldn't. malloc(), calloc(), and realloc() are part of the standard C memory manager. Check this out:
int *i = malloc(1);
This will return a pointer to a block of memory that is not big enough to accomodate the size of an int.
int *i = (int *)malloc(1);
This code still erroneous. So therefore I do not understand why people take issue with the cast (which is meaningless) if the only provision here is compatibility with older compilers. I did take note that syntax can be an issue with some compilers, however, a compiler that gives you grief over simple code such as this is not not a great compiler. If you look through my code you will always see a cast in front of all my mallocs, callocs, and reallocs only out of habbit. This is an issue of personal opinion.
quzah
10-08-2002, 02:29 AM
int *i = malloc(1);
And like the other absurd example given for reasons to typecast, only a fool would do this. And, just like the other example, there is no point to type casting this mistake, because with or without the typecast, you still end up with incorrect code and the type cast has no effect what so ever. Neither one produces an error. Neither one produces a warning. Neither one will fix your broken code. Like I've said: There is no reason to ever cast malloc. The only remote examples provided are so absurd they'd never happen in real life, or if they did, they'd happen by a total novice coder who wouldn't benifit either way from the cast, or without it.
Quzah.
By the way, can any body expain how to use realloc() function, and it is better to use a example.
Thanx for help!
Fordy
10-08-2002, 03:25 AM
Originally posted by pnxi
By the way, can any body expain how to use realloc() function, and it is better to use a example.
Thanx for help!
Try a search (http://www.cprogramming.com/cboard/search.php?s=&action=showresults&searchid=132283&sortby=lastpost&sortorder=descending)
vBulletin® v3.7.0, Copyright ©2000-2008, Jelsoft Enterprises Ltd.