473,698 Members | 2,508 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

malloc and functions

I am having an issue with malloc and gcc. Is there something wrong
with my code or is this a compiler bug ?

I am running this program:

#include <stdio.h>
#include <stdlib.h>

typedef struct pxl {
double lon, lat;
double x,y,z;
double px,py;
} pixel;
struct chn {
int index;
struct nde *node;
};

struct nde {
pixel position;
struct chn *forward;
struct chn *reverse;
int *chain_num;
int size;
};

typedef struct chn chain;
typedef struct nde node;

node *createnode( );

main()
{

node *startn;

startn = createnode( );

startn->size = 2;
startn->forward = malloc( 2 * sizeof( chain * ) );
startn->reverse = malloc( 2 * sizeof( chain * ) );

printf("sf %p\nsr %p\n\n",
startn->forward,
startn->reverse
);

printf("sf %p\nsr %p\n\n",
startn->forward,
startn->reverse
);

}

node *createnode( )
{
node *node;
node = malloc( sizeof(node) );
return node;
}

I get the following output.

sf 0x660168
sr 0x660178

sf 0xa383731
sr 0x660178

The startn->forward point changes between the two printfs despite
there being no code between them.

Jul 15 '07
23 2712
raphfrk wrote:
I am having an issue with malloc and gcc. Is there something wrong
with my code or is this a compiler bug ?
[...]
node *createnode( )
{
node *node;
node = malloc( sizeof(node) );
return node;
}
Giving variables with the same identifier as one you use for a type is
just asking for trouble. Compare the above with

node *createnode( )
{
node *nodeptr;
nodeptr = malloc(sizeof(n ode));
return nodeptr;
}

or with

node *createnode( )
{
node *nodeptr;
nodeptr = malloc(sizeof *nodeptr);
return nodeptr;
}
Jul 15 '07 #11
On Jul 15, 4:34 pm, Robert Gamble <rgambl...@gmai l.comwrote:
On Jul 15, 10:57 am, raphfrk <raph...@netsca pe.netwrote:
node = malloc( sizeof(node) );

Hint: Does sizeof apply to the typedef name or the variable name?
It's probably not what you expect.
You should also check the return value of malloc for failure.
This is the main problem. I went through the original program and
checked every malloc assignment. I didn't get the sizeof argument
correct in a few other places.

I had one for an array of the form:

char *array;

array = malloc( 100*sizeof( char * ) )
Fix the issues mentioned above and let us know if you still have a
problem.

Robert Gamble
It seems to have fixed it (and other bug), by checking every sizeof
one at a time.

Thanks alot all.

Jul 15 '07 #12
In article <11************ **********@o61g 2000hsh.googleg roups.com>
raphfrk <ra*****@netsca pe.netwrote:
>I am having an issue with malloc and gcc.
Issues with malloc() quite often boil down to one or more of
three things:

- Failure to include <stdlib.h>. This one is short and mostly
self-explanatory.

- Not using the "comp.lang. c Standard Approved Method" of
calling malloc() :-) The "approved method" says that if
you a pointer variable "p" of type "T *", i.e.:

T *p;

the call to malloc() should have the form:

p = malloc(N * sizeof *p);

where N is the number of items to allocate -- if this is 1
it may be omitted -- and "sizeof *p" is literally just that:
the keyword "sizeof", the unary "*" operator, and the name
of the variable on the left of the "=" sign.

The sizeof operator (and its argument, *p in this case) can
be omitted only if "T" is some variant of "char". Since
sizeof(char), sizeof(signed char), and sizeof(unsigned char)
are all 1 byte definition, and N*1 is just N, it is OK to
write:

char *copy;
...
copy = malloc(strlen(o riginal) + 1);

even though the "c.l.c. Standard Approved Method" would have
one write:

copy = malloc((strlen( original) + 1) * sizeof *copy);

- Forgetting to add one to strlen(some_str ing) to account
for the fact that a string whose length is L requires L+1
bytes of storage. (For instance, the empty string, "", has
zero length and requires one byte to store its '\0'; a
string of length three like "abc" requires four bytes to
store 'a', 'b', 'c', and '\0'; and so on.)

In this case, the first and last seem to be OK here, but the
middle is a big problem.
>I am running this program:

#include <stdio.h>
#include <stdlib.h>
Good: <stdlib.his included.
>typedef struct pxl {
double lon, lat;
double x,y,z;
double px,py;
} pixel;
(If you are going to use the "typedef" keyword at all, I prefer to
separate it out. See <http://web.torek.net/torek/c/types2.html>.
Note that this is purely a style issue; there is nothing incorrect
with the code above. It may affect the rest of your structures,
though.)
>struct chn {
int index;
struct nde *node;
};

struct nde {
pixel position;
struct chn *forward;
struct chn *reverse;
int *chain_num;
int size;
};
Note that a "struct nde"'s "forward" and "reverse" elements have
type "struct chn *", i.e., pointer to "struct chn".
>typedef struct chn chain;
typedef struct nde node;

node *createnode( );
Better to write "node *createnode(voi d);". This is purely a style
issue -- the code is right either way -- but using prototypes is
wise.
>main()
{
Better to write "int main(void)". (Not *wrong*, at least in C89,
though C99 requires the leading "int" part.)
>
node *startn;

startn = createnode( );

startn->size = 2;
startn->forward = malloc( 2 * sizeof( chain * ) );
startn->reverse = malloc( 2 * sizeof( chain * ) );
These two calls to malloc do not have the "c.l.c. Standard Approved
Form". Thus, there is a good chance they are wrong. Are they? Let
me compare them to the "approved method" versions, for which the
second line would read:

startn->reverse = malloc(2 * sizeof *startn->reverse);

In both cases, we have "N * sizeof..." where N is 2. So far, so
good -- we want two elements so that we can do:

startn->reverse[0] = some_val;
startn->reverse[1] = another_val;

-- and assuming the malloc() works and the sizes are right, we
should get that. Are the sizes right?

The "non-clc version" uses sizeof(chain *). Here "chain" is a
typedef-alias for "struct chn", so this asks for sizeof(struct
chn *): the size, in C bytes, of a "pointer to struct chn".

For numeric-concreteness purposes let me assume you are using a
typical IA32 system, in which sizeof(struct chn *) is 4, and
sizeof(struct chn) is 8. (If you were on an IA64 system, the sizes
would be 8 and 16, or possibly 8 and 12, respectively. Other
machines may have yet other sizes, but this is probably enough in
the way of examples.) So this asks for 2*4 bytes -- 8 bytes.

The "clc version", on the other hand, uses sizeof(*startn->reverse).
Now, startn->reverse has type "pointer to struct chn", so applying
a unary "*" operator to follow that pointer would produce an object
of type "struct chn". Hence, this is the as sizeof(struct chn),
which -- using the assumptions above -- is 8. So this asks for
2*8, or 16, bytes.

In other words, the sizes are *not* right. This is certainly *a*
problem, if not "the" (entire) problem.
printf("sf %p\nsr %p\n\n",
startn->forward,
startn->reverse
);
Technically you need to convert the two pointer arguments to
"void *" here, although it will work on both IA32 and IA64 example
architectures. In fact, there are almost no machines today on
which the cast changes the underlying machine code. But "almost
no machines" is slightly different from "no machines": if you ever
find yourself compiling on a Data General Eclipse, the code would
behave oddly without such a conversion. It is safer (as in,
guaranteed to be 100% correct, instead of almost-always-works-
but-not-guaranteed) to do, e.g.:

printf("sf %p\nsr %p\n\n",
(void *)startn->forward,
(void *)startn->reverse);

[some snippage]
>node *createnode( )
{
node *node;
node = malloc( sizeof(node) );
return node;
}
Others have pointed out the danger of having too many things named
"node" in the same name-space. (Cf. the "party at which everyone is
named Chris" in the web page I referred to above. In part because
"struct"s have their own name-space, I prefer not to use typedefs
at all.) In this case, that, plus avoiding the "clc-approved form",
result in:

malloc(sizeof node)

asking for sizeof <the variablebytes. On IA32, sizeof <the
variableis 4, while sizeof(struct nde) is 72 -- so this asks for
4 bytes instead of 72. Even with the "everyone-has-the-same-name"
confusion, though, if you had written:

node = malloc(sizeof *node);

this would have asked for sizeof <*(the variable)bytes, and since
the variable has type "pointer to struct nde", and the unary "*"
removes the "pointer to" part, you would have asked for
sizeof(struct nde) bytes -- assuming IA32 again, the 72 you need
here.
--
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.
Jul 15 '07 #13
raphfrk <ra*****@netsca pe.netwrites:
On Jul 15, 4:34 pm, Robert Gamble <rgambl...@gmai l.comwrote:
>On Jul 15, 10:57 am, raphfrk <raph...@netsca pe.netwrote:
node = malloc( sizeof(node) );

Hint: Does sizeof apply to the typedef name or the variable name?
It's probably not what you expect.
You should also check the return value of malloc for failure.

This is the main problem. I went through the original program and
checked every malloc assignment. I didn't get the sizeof argument
correct in a few other places.

I had one for an array of the form:

char *array;

array = malloc( 100*sizeof( char * ) )
[...]

That's why we here in comp.lang.c recommend a consistent idiomatic
form for malloc calls. For the example above, it would be:

char *array;

array = malloc(100 * sizeof *array);

(or, better yet, you'd use a defined constant rather than the magic
number 100).

By using the name of the target pointer object in the sizeof
expression, you can write a correct expression that will remain
correct even if you change (or forget) the type of the pointer.

Incidentally, I probably wouldn't use the name 'array' for a pointer
object. It points to (the first element of) an array, but it isn't an
array itself. In generic or sample code, I'd probably call it
something like "ptr". In real-world application code, I'd give it a
name that reflects what it's actually used for rather than it's C
type.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 15 '07 #14
On Jul 15, 3:38 pm, Chris Torek <nos...@torek.n etwrote:
In article <1184511435.763 565.302...@o61g 2000hsh.googleg roups.com>

raphfrk <raph...@netsca pe.netwrote:
I am having an issue with malloc and gcc.

Issues with malloc() quite often boil down to one or more of
three things:

- Failure to include <stdlib.h>. This one is short and mostly
self-explanatory.
Why doesn't this trigger a warning ? In fact, how does it know
what malloc is supposed to return ?
>
- Not using the "comp.lang. c Standard Approved Method" of
calling malloc() :-) The "approved method" says that if
you a pointer variable "p" of type "T *", i.e.:

T *p;

the call to malloc() should have the form:

p = malloc(N * sizeof *p);
Good plan, I will change my malloc calls to that.

sizeof isn't a function ?

I assume

p = malloc( N * sizeof( *p ) );

is just as good.

Jul 16 '07 #15
raphfrk wrote:
On Jul 15, 3:38 pm, Chris Torek <nos...@torek.n etwrote:
>In article <1184511435.763 565.302...@o61g 2000hsh.googleg roups.com>

raphfrk <raph...@netsca pe.netwrote:
>>I am having an issue with malloc and gcc.
Issues with malloc() quite often boil down to one or more of
three things:

- Failure to include <stdlib.h>. This one is short and mostly
self-explanatory.

Why doesn't this trigger a warning ? In fact, how does it know
what malloc is supposed to return ?
for almost all compilers I know, it does, if you haven't told the
compiler to shut up by (a) casting the return value from malloc or (b)
setting your diagnostics at a pathetically low level. Both are serious
programmer errors, but only by fixing the programmer can they be corrected.
> - Not using the "comp.lang. c Standard Approved Method" of
calling malloc() :-) The "approved method" says that if
you a pointer variable "p" of type "T *", i.e.:

T *p;

the call to malloc() should have the form:

p = malloc(N * sizeof *p);

Good plan, I will change my malloc calls to that.

sizeof isn't a function ?

I assume

p = malloc( N * sizeof( *p ) );

is just as good.
There is no difference, except the form 'sizeof *p' makes it clear that
(a) sizeof is not a function and (b) *p is an object. Those things are
obvious, but it is amazing what 'obvious' things are not so to
subsequent code maintainers.

Jul 16 '07 #16
raphfrk wrote, On 16/07/07 17:44:
On Jul 15, 3:38 pm, Chris Torek <nos...@torek.n etwrote:
>In article <1184511435.763 565.302...@o61g 2000hsh.googleg roups.com>

raphfrk <raph...@netsca pe.netwrote:
>>I am having an issue with malloc and gcc.
Issues with malloc() quite often boil down to one or more of
three things:

- Failure to include <stdlib.h>. This one is short and mostly
self-explanatory.

Why doesn't this trigger a warning ?
If you don't cast the result of malloc then the compiler *will* generate
a diagnostic (warning or error). If you use a cast then you are telling
the compiler you know what you are doing, but *some* compilers will be
helpful and bitch at you anyway.
In fact, how does it know
what malloc is supposed to return ?
If you include stdlib.h it knows because stdlib.h tell it, if nothing
tells it the compiler is *required* to assume malloc returns an int
which is incorrect.
> - Not using the "comp.lang. c Standard Approved Method" of
calling malloc() :-) The "approved method" says that if
you a pointer variable "p" of type "T *", i.e.:

T *p;

the call to malloc() should have the form:

p = malloc(N * sizeof *p);

Good plan, I will change my malloc calls to that.

sizeof isn't a function ?
No, it is an operator, just like +.
I assume

p = malloc( N * sizeof( *p ) );

is just as good.
The extra parenthesis are not required but do no harm. Just extra to type!
--
Flash Gordon
Jul 16 '07 #17
raphfrk <ra*****@netsca pe.netwrites:
sizeof isn't a function ?
No, and it is odd even for an operator:

#include <stdio.h>

int f(void) { return printf("In f()\n"); }

int main(void)
{
printf("%zd\n", sizeof f());
return 0;
}

--
Ben.
Jul 16 '07 #18
Ben Bacarisse <be********@bsb .me.ukwrites:
raphfrk <ra*****@netsca pe.netwrites:
>sizeof isn't a function ?

No, and it is odd even for an operator:

#include <stdio.h>

int f(void) { return printf("In f()\n"); }

int main(void)
{
printf("%zd\n", sizeof f());
return 0;
}
The "?:", "&&", and "||" operators also don't necessarily evaluate all
their operands.

I think the main reason for the confusion is that sizeof is the only
operator whose symbol is a identifier (specifically a keyword). The
fact that its operand either must be (for a type name) or can be (for
an expression) enclosed in parentheses just adds to the frivolity.

If C had used '$' rather than 'sizeof', nobody would think it's a
function -- but then there would have been problems in C's early
years, when keyboards with no '$' character were widespread.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 17 '07 #19
On Jul 17, 12:14 pm, Keith Thompson <ks...@mib.orgw rote:
If C had used '$' rather than 'sizeof', nobody would think it's a
function -- but then there would have been problems in C's early
years, when keyboards with no '$' character were widespread.
Also I've heard there are a lot of C programs
where '$' is used in identifiers, supported
by compiler extensions now of course.
Jul 17 '07 #20

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

Similar topics

22
2576
by: BekTek | last post by:
Hi.. I'm so sorry about that I've postes so many questions recently.. :) I'm still confused about the differences between malloc and operator new.. I know that when we work with class object and use operator new/delete, the ctor and dtor get called as expected, but malloc and free do not.. But Herbal Sutter mentioned in his greate book 'exceptional c++' about free storage
59
5166
by: Steve Zimmerman | last post by:
This program compiles fine, but are there any hidden dangers in it, or is it ok? Experiment 1 ################################################## #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <string.h>
36
6681
by: MSG | last post by:
The answer is neither. Use macros. #define ALLOC(size, type) ((type) *) malloc((size) * sizeof(type)) #define NEW(type, name, size) (type) * (name) = ALLOC((size), (type)) They are both type-safe and concise. Compare: NEW(int, x, 1000);
25
5064
by: H.A. Sujith | last post by:
If malloc fails what should I do? 1. Exit imediately. 2. Print an error message (or put a log entry) and exit. 3. Print an error message (or put a log entry) and continue execution (after possibly recovering from the error). Printing an error message might be difficult in a graphical environment. --
50
2845
by: Joseph Casey | last post by:
Greetings. I have read that the mistake of calling free(some_ptr) twice on malloc(some_data) can cause program malfunction. Why is this? With thanks. Joseph Casey.
12
7597
by: Anil | last post by:
Hi, Where can I get the source code that has the implementation of the below C operators/functions: malloc sizeof new strcmp strtok
68
15683
by: James Dow Allen | last post by:
The gcc compiler treats malloc() specially! I have no particular question, but it might be fun to hear from anyone who knows about gcc's special behavior. Some may find this post interesting; some may find it off-topic or confusing. Disclaimers at end. The code samples are intended to be nearly minimal demonstrations. They are *not* related to any actual application code.
10
2596
by: Yevgen Muntyan | last post by:
Consider the following macro: #define ALLOCIT(Type) ((Type*) malloc (sizeof (Type))) The intent is to wrap raw memory allocation of N bytes into a macro which returns allocated chunk of memory to be used as a Type structure. The background: I was beaten many times (it surely is not my exclusive experience) by functions which return and accept void*. There are such functions,
71
19103
by: desktop | last post by:
I have read in Bjarne Stroustrup that using malloc and free should be avoided in C++ because they deal with uninitialized memory and one should instead use new and delete. But why is that a problem? I cannot see why using malloc instead of new does not give the same result.
3
3618
by: Petr Pavlu | last post by:
Hello, I have two questions how the functions should be written. I read the FAQ but didn't find any answer. If there is any please point me out. I. Cleanup code Consider I have to open file1, then make some malloc and then open file2. What is the best solution how to write the cleanup code? See my pseudo- code ideas.
0
8685
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
9171
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
9032
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...
0
7743
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
6532
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
5869
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4625
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2342
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2008
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.