473,839 Members | 1,480 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 23297
On 26 Jan 2004 13:42:11 GMT,
Mark A. Odell <no****@embedde dfw.com> wrote
in Msg. <Xn************ *************** *****@130.133.1 .4>
Why would a C++ compiler need to worry about malloc()'ing code? They have
memory allocation schemes of their own in C++.


....and indeed, IIRC, you're recommended to only use new to allocate memory
in C++ anyway; malloc() is considered bad style. Which gives us yet
another reason against the cast: When C++ balks about an uncast malloc()
it's time to change it to "new" instead (and to get rid of the
corresponding free() as well). But this is OT on clc.

--Daniel

--
"With me is nothing wrong! And with you?" (from r.a.m.p)
Nov 14 '05 #181
On Thu, 29 Jan 2004 01:08:46 +0100,
Sidney Cadot <si****@jigsaw. nl> wrote
in Msg. <bv**********@n ews.tudelft.nl>
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).


Changing an (presumably unique) identifier name is a piece of cake unless
you use a mechanical typewriter for writing source code. But automatically
changing the multiply-used type of an object with a text editor is a bit
more difficult.

--Daniel

--
"With me is nothing wrong! And with you?" (from r.a.m.p)
Nov 14 '05 #182
On Thu, 29 Jan 2004 01:08:46 +0100,
Sidney Cadot <si****@jigsaw. nl> wrote
in Msg. <bv**********@n ews.tudelft.nl>
That way, I don't have to rely on the semantics of C with regard to
allowing void*-to-any* assignments,


When programming in C you have to rely on the semantics of C with regard
to pretty much anything.

--Daniel

--
"With me is nothing wrong! And with you?" (from r.a.m.p)
Nov 14 '05 #183
Tak-Shing Chan <es***@city.ac. uk> wrote:
On Wed, 28 Jan 2004, Richard Bos wrote:
As for the third argument, it is demonstrably false; and has been shown
to be false repeatedly in this newsgroup.
AFAICT it has /not/ been shown false. The lack of malloc
casts could actually hide undefined behaviors:


Not unless there is more wrong.
#include <stdio.h>
#include <stdlib.h>

double *x; /* Wrong declaration */
Very unusual. Generally one knows what kind of data one wants when one
declares it; only while using them do you sometimes get confused.
int
main(void)
{
x = (int *) malloc(sizeof *x);
if (x) {
*x = 4;
printf("%d\n", *x); /* Undefined behavior */
You know, I'd expect to get a warning; and I'd expect malloc()-casters
to cast away that warning by writing

printf("%d\n", (int)*x);

or even

printf("%d\n", *(int *)x);
With the malloc cast, you are guaranteed a diagnostic.
Without the cast, the diagnostic is not required. Bad style
perhaps, but this possibility should not be dismissed.


Actually, I do dismiss this possibility, because I don't believe it
happens that way.

Moreover, it is not a reason to cast malloc() in particular. Would you
also expect to see the cast on

int *y;

y = (int *)x;

If not, why make an exception for malloc()?

Richard
Nov 14 '05 #184
Daniel Haude wrote:

On Mon, 26 Jan 2004 22:54:26 GMT,
P.J. Plauger <pj*@dinkumware .com> wrote
in Msg. <CU************ ***@nwrddc01.gn ilink.net>
1) Style rules should be developed by considering all applicable
principles and weighing their various importance *for that particular
rule*.


So if you write a function that expects a void pointer but uses
another type internally (like the compare function for qsort),
would you do it like this?

int foo(void *a)
{
struct whatever_struct *s = (struct whatever_struct *) a;
/* ... */
}


No.

struct whatever_struct *s = a;

a needs to be holding a valid (struct whatever_struct *) type
value to begin with, or your code's no good.

void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *))
{
unsigned char swap, *p1, *p2, *end, *array, *i, *j, *k, *after;
size_t bytes;

array = base;
after = nmemb * size + array;
if (nmemb > (size_t)-1 / 3) {
nmemb = (size_t)-1 / 3;
}
do {
bytes = nmemb * size;
for (i = bytes + array; i != after; i += size) {
j = i - bytes;
if (compar(j, i) > 0) {
k = i;
do {
p1 = j;
p2 = k;
end = p2 + size;
do {
swap = *p1;
*p1++ = *p2;
*p2++ = swap;
} while (p2 != end);
if (bytes + array > j) {
break;
}
k = j;
j -= bytes;
} while (compar(j, k) > 0);
}
}
nmemb = nmemb != 2 ? 3 * nmemb / 8 : 1;
} while (nmemb);
}

--
pete
Nov 14 '05 #185
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.
Does compilers treat them differently?


Nov 14 '05 #186
Sidney Cadot wrote:
Holger Hasselbach wrote:
Do you rely on the promotion rules? Do you think that the rules with
all the implicit conversions between signed/unsigned int types, float,
double, etc. for numbers provide more type safety than the void* to
any* conversions for pointers? Or do you always write something like
this:

char c = (char)((int)'0' + (int)9);


I rely on the rules that I think are reasonable. This includes your
sample case (so I don't use casts there), and things like implicit
int-to-float conversion.

I do not rely on the rules that I think are unreasonable. This includes
implicit void*-to-any* conversions, but also implicit float-to-int
conversions.

So I would never write:

intVar = floatVar;

But I would always use an explicit cast (and only in cases where I do
not care too much about rounding).


Occasionally I use explicit casts in that case, too, to silence
over-paranoid compilers ("It's my intention to be unprecise, so shut
up!"). In full awareness that it could introduce serious unwarned bugs
when the intVar is later changed to a longVar without modifying the
cast, when the type is not abstracted by a typedef. But that's another
thing than to not rely on it. To not rely on it has something of to
not trust its correctness of implementation or the correctness of the
rules themself.

Why exactly do you think that the float-to-int conversion is
unreasonable?

Do you think that an explicit conversion is "more correct" than an
implicit one? I'm quite sure that any existing conforming compiler
will produce exactly the same result in intVar for both cases.

Why exactly do you think that the void*-to-any* conversion is
unreasonable? What exactly could go wrong in the implicit semantics?

Did you have any situations where you experienced the failure of the
implicit conversions (in both int and void), which you successfully
cured with an explicit cast? And that you could blame on the
semantics, not on a broken non-conforming compiler?
As I previously wrote far below in the thread, there are three
situations where, for a pointer d, the types of d and *d are relevant:


Only three?


Can you give another one that does not fit into one of these three?

[...]
Holger
Nov 14 '05 #187
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.

Richard
Nov 14 '05 #188
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.

Best regards, Sidney

Nov 14 '05 #189
magesh 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
Nobody is pretending that. Both sides agree that not including
<stdlib.h> before using malloc() is very wrong, it is this which causes
UB. Casting or not casting the result of malloc will not lead to
undefined behavior in itself.
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.
It's not ok for some (most, actually) for what I'd like to call
stylistic reasons.
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 you can show me a plausible scenario for this, I'd welcome it. In
practice, malloc() results are almost always assigned to a typed pointer.
If we prentend that implicit conversion is safe
No reason to pretend, it is safe (for the result of malloc, anyway).
and the fact of casting
may cause UB due to probable alignement problems,
Not for a malloc() result, which is guaranteed to be properly aligned
for conversion to basically any type of pointer.
its a bit difficult to
understant why implicit conversion may be safer than an explicit more
than a matter of style.
It is claimed to be safer more from a code-maintenance point of view. In
this respect, some valid arghments do indeed exist.
Does compilers treat them differently?


As far as I know, there are no circumstances where x=y (with x of type
T* and y of type void*) yields a different semantics than x=(T*)y ; if
this is true, it is probable that any real-life compiler will treat
these equivalently.

Best regards,

Sidney
Nov 14 '05 #190

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

Similar topics

33
2295
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
2719
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
2399
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
4374
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
9854
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
9696
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10903
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
10290
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9425
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...
1
7827
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5681
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...
0
5865
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4482
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

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.