473,854 Members | 1,511 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

why is casting malloc a bad thing?

Hello,

I saw on a couple of recent posts people saying that casting the return
value of malloc is bad, like:

d=(double *) malloc(50*sizeo f(double));

why is this bad? I had always thought (perhaps mistakenly) that the
purpose of a void pointer was to cast into a legitimate date type. Is
this wrong? Why, and what is considered to be correct form?

thanks,

Brian Blais

Nov 14 '05
231 23330
Chris Torek wrote:
[snipped a well-balanced article concerning malloc() casting]


Amen to all that. I think you have accurately conveyed the majority view
here, while at the same time giving some attention to opposing views
without dismissing them out of hand. If something along these lines
could end up in the FAQ, that would be great.

Best regards, Sidney

Nov 14 '05 #211
In article <40************ **********@news .club-internet.fr>,
magesh <ma*****@club-internet.fr> wrote:
Well I am not sure to measure upto u guys, my question may be redundnant.
My question is this, if people pretend with their own arguments
that casting malloc return may cause undefined behaviour, I would like
to know

double* p = malloc(8*sizeof (double));==>OK for some here because
implicit coversion is well enough
but why
double* p = (double*) malloc(8*sizeof (double));==>NO K for some.

I assume that casting the malloc's return is just an indication for my
codevelopers who may see an assignement of p from a malloc a 500 or more
lines after my pointer declaration p.

If we prentend that implicit conversion is safe and the fact of casting
may cause UB due to probable alignement problems, its a bit difficult to
understant why implicit conversion may be safer than an explicit more
than a matter of style.


You missed the point completely. Correct casts are not a problem at all.
Incorrect casts are a problem. The compiler doesn't know whether a cast
is correct or incorrect. That leads to the principle that you should
_never_ use a cast unless you cannot avoid it.

int* p = malloc (2 * sizeof (int));
int* p = (int *) malloc (2 * sizeof (int));

do exactly the same thing. The cast has been used correctly. It didn't
do any damage, but it didn't help either.

extern int nalloc (size_t size);

int* p = nalloc (2 * sizeof (int));
int* p = (int *) nalloc (2 * sizeof (int));

In this case, the compiler can catch the error in the first statement,
but not in the second one. The cast did hide the error.

Apply the general principle (never cast unless it cannot be avoided),
and it is obvious that you shouldn't cast the result of malloc.
Nov 14 '05 #212
In article <bv**********@n ews.tudelft.nl> ,
Sidney Cadot <si****@jigsaw. nl> wrote:
Richard Bos wrote:
magesh <ma*****@club-internet.fr> wrote:

Well I am not sure to measure upto u guys, my question may be redundnant.
My question is this, if people pretend with their own arguments
that casting malloc return may cause undefined behaviour,

Nonsense - nobody has "pretended" that. Casting malloc() may _hide_
undefined behaviour which is present in the code whether there is a cast
or not. If you call malloc() without a declaration in scope for it, you
always invoke undefined behaviour. The cast doesn't change that fact.

What it does do is stop the compiler from telling you about it.


No, it does not actually. This argument may have been relevant 10 years
ago, but it is no longer. Sure, it's not a required diagnostic in C89
mode, but any halfway decent compiler is able to warn about an
undeclared malloc() nowadays.

If you don't use the appropriate command line options to enable such
warnings, that's more of a problem than casting malloc results can ever be.

In short, I think this argument is stale, and is getting staler all the
time.


It helps you in case you spelt the function name incorrectly.
Nov 14 '05 #213
In article <bv**********@s unnews.cern.ch> , Da*****@cern.ch (Dan Pop)
wrote:
In <bv**********@n ews.tudelft.nl> Sidney Cadot <si****@jigsaw. nl> writes:
Dan Pop wrote:
If you ever have to change identifier names in your code, there is
something very wrong with your coding methodology.


To me, that sounds like a bizarre statement. Please elaborate.


The only *good* reason for renaming an identifier is because the original
name was improperly chosen. Hence my "bizarre" statement above.


The original name may have been chosen properly according to the
requirements that you knew at that time. When requirements change,
meanings can change and a name may not be chosen properly anymore.
Nov 14 '05 #214
Christian Bau wrote:
extern int nalloc(size_t size);

int* p = nalloc(2*sizeof (int));
int* p = (int*)nalloc(2* sizeof(int));

In this case, the compiler can catch the error in the first statement,
but not in the second one. The cast did hide the error.


In this case, your example begs the question,
"What was the error in this example?"
Was nalloc supposed to return a pointer to an int?

Nov 14 '05 #215
In article <40**********@j pl.nasa.gov>,
"E. Robert Tisdale" <E.************ **@jpl.nasa.gov > wrote:
Christian Bau wrote:
extern int nalloc(size_t size);

int* p = nalloc(2*sizeof (int));
int* p = (int*)nalloc(2* sizeof(int));

In this case, the compiler can catch the error in the first statement,
but not in the second one. The cast did hide the error.


In this case, your example begs the question,
"What was the error in this example?"
Was nalloc supposed to return a pointer to an int?


I'll have to repeat myself:

"Tisdale, you idiot, go away!"
Nov 14 '05 #216
magesh <ma*****@club-internet.fr> wrote in message news:<40******* *************** @news.club-internet.fr>...

I completely agree with the fact that proper header files should be
included, I would be amazed a proper C file that never calls a function
from stdlib, so normal programmers include them, if they give attention
to warnings from the compiler or else this thread is not meant for them.
But that's the whole point! Assume the programmer makes a mistake
and forgets to include the header. If he casts the return value from
malloc() he does not necessarily get a diagnostic; some compilers
give one if invoked in certain ways, many do not give one by default,
some do not give one no matter how they are invoked. On the other
hand, if he does not cast the return from malloc(), all C compilers
must give a diagnostic. Without the cast you will always get a
message; with the cast you might or might not get a message.

I remember one poster here presenting some sample code that included
a cast on malloc(). He was advised to remove the cast, and patiently
explained that he'd had to add the cast because without it he got
some strange message about 'invalid assignment'. If the mantra
'never cast malloc()' had been burned into his brain, he would have
had to think a little more or ask around to find what his bug was.
declaration of p 1000 lines before.
1001: p= malloc(sizeof(* p)*10);

could you tell me what type is p, while u are going through just this
part of ur code.
1) It is atrocious style to declare a pointer 1000 lines earlier,
especially if it is not used regularly enough for the reader to
already know what it is. Such code is unmaintainable.

2) Why do you care what type it is at the point where you malloc()
it? You might need to know soon afterwards, but I don't regard a
cast on a call to malloc() as an apropriate way of commenting code!
Reagrding code maintenance, the other solution p= malloc(sizeof(* p)*10);
may be easy to change the type of p without changing the malloc line in
ur code, after that?? the fact that the type of p has changed may have
more impact on other lines where u use them, than those on one malloc
statement!!!


Indeed, and the fewer such changes there are to be made, the more
likely that they'll be made correctly. The fewer changes there are,
the more quickly the overall update can be made. The fewer changes
there are, the lower the risk of introducing bugs. Maintainable
reliable code is written to adapt itself automatically to changes
as much as possible.
Nov 14 '05 #217
J. J. Farrell wrote:
magesh wrote:
I completely agree with the fact that proper header files should be
included, I would be amazed a proper C file that never calls a function
from stdlib, so normal programmers include them, if they give attention
to warnings from the compiler or else this thread is not meant for them.
But that's the whole point! Assume [that]
the programmer makes a mistake and forgets to include the header.
If he casts the return value from malloc(),
he does not necessarily get a diagnostic;
some compilers give one if invoked in certain ways,
many do not give one by default,
some do not give one no matter how they are invoked.
Why should C programmers cobble their code
just to accommodate inferior C compilers?
On the other hand, if he does not cast the return from malloc(),
all C compilers must give a diagnostic.


A cryptic an misleading diagnostic if it doesn't tell the programmer
that the definition of malloc is missing.

Nov 14 '05 #218
Dan Pop <Da*****@cern.c h> wrote:
In <bv**********@n ews.tudelft.nl> Sidney Cadot <si****@jigsaw. nl> writes:
Dan Pop wrote:
Casting to double * not only doesn't add anything, because there is no
place left for the error you're talking about, but it is a maintenance
headache if the type of x ever needs to be changed, say to pointer
to long double: instead of making one change, you have to make two,


That's true. In fact, it's more of a "maintenanc e headache" than what
your preferred notation introduces when changing the identifier name
(but only slightly).


If you ever have to change identifier names in your code, there is
something very wrong with your coding methodology.


I admit that from time to time it becomes necessary to change an
identifiers name. That would IMHO be probably only be necessary with
file scope identifiers, as the usage of local identifiers is probably so
clear when you first type its name that it happens rather seldom to me
that I have to change its name. Sometimes when a file scope identifier
is not named carefully, it may become necessary to change its name, but
than there are tools to change one string into another, most editors can
do this within one step and if the usage is split over more files
"sed"-like tools are your friend.

IMHO it is very much easier to change an idenitifier everywhere it is
used, than searching all the code for "assumption s" about the type of an
identifier.

--
Z (Zo**********@d aimlerchrysler. com)
"LISP is worth learning for the profound enlightenment experience
you will have when you finally get it; that experience will make you
a better programmer for the rest of your days." -- Eric S. Raymond
Nov 14 '05 #219
Someone notes that, if one follows the "comp.lang. c accepted
practice" of not casting malloc() return values, and uses most
ordinary C89/C90 compilers in their default non-warning modes
so that one gets only the required diagnostics, forgetting to
"#include <stdlib.h>" produces:
A cryptic an misleading diagnostic if it doesn't tell the programmer
that the definition of malloc is missing.


For example, if one were to write:

struct zorg *new_zorg(doubl e degree_of_eviln ess) {
struct zorg *new = malloc(sizeof *new);

new->degree = degree_of_eviln ess;
return new;
}

and feed it to the Generic C Compiler, one might get:

% cc -c zorg.c
zorg.c: In function `new_zorg':
zorg.c:4: warning: initialization makes pointer from integer without a cast

It is certainly true that this warning leaves something to be
desired. The problem is not making a "pointer from integer",
but rather with "malloc never explicitly declared, thus implicitly
declared instead". Nonetheless, this is hardly a *new* problem:

% cc -c oops.c
oops.c:6: syntax error before `for'
% cat oops.c
/* kind of like strlen() but returns an int *./
int like_strlen(con st char *p) {
int i;

/* we just need to find the first p[i] that is '\0' */
for (i = 0; p[i] != 0; i++)
continue;
return i;
}

There is nothing wrong on line 6, nor line 5, nor 4 (blank), nor
3, nor even line 2 -- the problem is all the way back on line 1,
where a typographic error inserted a period between the * and /
meant to close the comment. There are all kinds of constructs like
this, where a compiler issues the wrong message. Programmers *need*
to learn not to trust where the machine points, in the same way
that automobile mechanics need to learn not to assume that, if the
On Board Diagnostics in an engine computer says "oxygen sensor
failure", it is not necessarily the sensor itself that failed.
(The problem can be in the wire connecting the sensor to the
computer. The sensor is a "replacemen t item" -- the ones in the
exhaust system in particular may have only a few years' lifetime
-- so the diagnostic is *usually* right, but not always.)

It is always a good idea to compare the machine's complaint against
what you (believe you) know to be the case. If the machine says
"you are making a pointer from an integer", but you know malloc()
does not return an integer, then you should ask yourself: where is
this integer? Why does the compiler believe there is an integer
here? Then, if all else fails, you could even post to comp.lang.c:

"I have this C code here, and the compiler is giving me a
message involving an `integer' when there is no integer.
Why is that?"

Ideally, you should include a complete, compileable chunk of code,
and the exact text of the error or warning message, too. But the
goal here -- besides fixing the problem -- is learning why a C
compiler might think there is an integer here, when you are certain
there is none. Then you will hear all about "implicit int function
declarations", why they are bad, that your compiler needs a tuneup
(e.g., "-Wmissing-declarations") if not a complete replacement,
and of course the inevitable cascade of "don't cast malloc in C /
compile your C code with an Ada-I-mean-C++-compiler" flamage. :-)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #220

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

33
2300
by: hermit_crab67 | last post by:
Can someone explain to a C newbie why this doesn't work as I expect it to work? (expectations clearly outlined in the printf statement in main routine) OS: Linux 2.4.26 GCC: 2.95.4 void modify_pointer(char *); int main(int argc, char *argv) {
35
2721
by: ytrama | last post by:
Hi, I have read in one of old posting that don't cast of pointer which is returned by the malloc. I would like to know the reason. Thanks in advance, YTR
32
2403
by: alex.j.k2 | last post by:
Hello all, I have "PRECISION" defined in the preprocessor code and it could be int, float or double, but I do not know in the code what it is. Now if I want to assign zero to a "PRECISION" variable, which of the following lines are correct:
101
4381
by: Tinkertim | last post by:
Hi, I have often wondered if casting the return value of malloc() (or friends) actually helps anything, recent threads here suggest that it does not .. so I hope to find out. For instance : char *tmp = NULL;
0
9901
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
11031
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10685
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10763
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9518
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5750
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4563
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4162
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3188
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.