Arraym malloc() and free() question

M

Martin Andert

Hello,
I have a question regarding malloc and free.
Here my code sample:

int main()
{
/* allocating dynamic memory for array */
int* array = (int*) malloc(5 * sizeof(int));

/* ... program code ... */

array = (int*) malloc(4 * sieof(int));

free(array);
}

Now my question: The second time I allocate
memory for array, what happens to the
address that I got with the first malloc?
Is it freed automatically?

Martin
 
B

Ben Pfaff

int main()
{
/* allocating dynamic memory for array */
int* array = (int*) malloc(5 * sizeof(int));

I don't recommend casting the return value of malloc():

* The cast is not required in ANSI C.

* Casting its return value can mask a failure to #include
<stdlib.h>, which leads to undefined behavior.

* If you cast to the wrong type by accident, odd failures can
result.

Some others do disagree, such as P.J. Plauger (see article
<[email protected]>).

When calling malloc(), I recommend using the sizeof operator on
the object you are allocating, not on the type. For instance,
*don't* write this:

int *x = malloc (128 * sizeof (int)); /* Don't do this! */

Instead, write it this way:

int *x = malloc (128 * sizeof *x);

There's a few reasons to do it this way:

* If you ever change the type that `x' points to, it's not
necessary to change the malloc() call as well.

This is more of a problem in a large program, but it's still
convenient in a small one.

* Taking the size of an object makes writing the statement
less error-prone. You can verify that the sizeof syntax is
correct without having to look at the declaration.
/* ... program code ... */

array = (int*) malloc(4 * sieof(int));

free(array);
}

Now my question: The second time I allocate
memory for array, what happens to the
address that I got with the first malloc?
Is it freed automatically?

No. If you didn't save a copy of the original pointer, the
memory is wasted ("leaked").
 
G

Gordon Burditt

I have a question regarding malloc and free.
Here my code sample:

int main()
{
/* allocating dynamic memory for array */
int* array = (int*) malloc(5 * sizeof(int));

/* ... program code ... */

array = (int*) malloc(4 * sieof(int));

free(array);
}

Now my question: The second time I allocate
memory for array, what happens to the
address that I got with the first malloc?

You have a memory leak (assuming you didn't save the address
elsewhere). This is a BAD THING (tm).

A memory leak should not cause crashing in a properly written program
(CHECK if malloc() returns NULL before using the result!) but it
may cause malloc() to fail, especially if the leak is in a loop.
Is it freed automatically?

Memory allocated with malloc() is not freed automatically, except
perhaps when the program calls exit().

Gordon L. Burditt
 
E

E. Robert Tisdale

Ben said:
> cat main.c
int main(int argc, char* argv[]) {
// allocating dynamic memory for array
int* array = (int*)malloc(5*sizeof(int));

// ... program code ...

array = (int*)malloc(4*sizeof(int));// error: memory leak!

free(array);
return 0;
}
> gcc -Wall -std=c99 -pedantic -o main main.c
main.c: In function `main':
main.c:3: warning: implicit declaration of function `malloc'
main.c:9: warning: implicit declaration of function `free'
I don't recommend casting the return value of malloc():

* The cast is not required in ANSI C.

* Casting its return value can mask a failure to
#include <stdlib.h>, which leads to undefined behavior.

Nonsense!
Only inferior compiler fail to warn about
implicit declaration of function `malloc'
 
M

Martin Ambuhl

Martin Andert wrote, without checking the FAQ or following the newsgroup
before posting:
Hello,
I have a question regarding malloc and free.
Here my code sample:

You need to
#include <stdlib.h>
No doubt the reason for the silly casts on the return value from malloc
was to make the compiler shut up. Leaving out this header (or the
equivalent declarations and definitions found there) means your C89
compiler assumes incorrectly that malloc returns an int. When you get a
C99 compiler, it will barf instead, since implicit int is gone.
int main()
{
/* allocating dynamic memory for array */
int* array = (int*) malloc(5 * sizeof(int));

I think you mean
int *array = malloc(5 * sizeof *array);
That magic number (5) is poor practice, and you should check the return
value of malloc. Of course, people following expected usenet behavior
would know that, because they would have checked the FAQ and followed
the newsgroup.
/* ... program code ... */

array = (int*) malloc(4 * sieof(int));
See the comments above. In addition, you need to either free array
before this malloc call or use realloc instead.
free(array);
}

Now my question: The second time I allocate
memory for array, what happens to the
address that I got with the first malloc?
You lost it. You have a memory leak.
Is it freed automatically?
No.

Martin

People named 'Martin' should know to check the FAQ and follow the
newsgroup before posting.

Martin
 
K

Keith Thompson

E. Robert Tisdale said:
Ben Pfaff wrote: [...]
I don't recommend casting the return value of malloc():
* The cast is not required in ANSI C.
* Casting its return value can mask a failure to
#include <stdlib.h>, which leads to undefined behavior.

Nonsense!
Only inferior compiler fail to warn about
implicit declaration of function `malloc'

Perhaps, but there's no reason to depend on your compiler to issue
this (common but not universal) warning.

With the cast, if you forget to #include <stdlib.h>, you'll *probably*
get a warning about the call to malloc() with no visible prototype.
(gcc 3.3.3 doesn't give this warning by default; it does if you
specify "-Wall". Yes, you should always use "-Wall", but not everyone
does.)

Without the cast, if you forget to #include <stdlib.h>, you'll *almost
certainly* get an additional diagnostic about an implicit conversion
from type "int".

And of course if you properly #include <stdlib.h> *and* leave out the
cast, everything will work just fine.

The cast is completely unnecessary unless, for some reason, you
actually need to write code that's compatible with both C and C++
(C++, unlike C, has no implicit conversion from void* to other pointer
types). Very few people have such a need. <OT>Pure C++ code should
use new rather than malloc().</OT>

ERT attempts to refute Ben's second point, that the cast can mask a
failure to #include <stdlib.h>. But his first point, that the cast is
not required, is much stronger. Why use a cast when it's not needed?
 
A

Alex Fraser

[snip]
With the cast, if you forget to #include <stdlib.h>, you'll *probably*
get a warning about the call to malloc() with no visible prototype. [snip]
Without the cast, if you forget to #include <stdlib.h>, you'll *almost
certainly* get an additional diagnostic about an implicit conversion
from type "int".

Only "almost certainly"? Isn't assignment of an int to a pointer a
constraint violation, which therefore requires a diganostic?

Alex
 
D

Dan Pop

In said:
E. Robert Tisdale said:
Ben Pfaff wrote: [...]
I don't recommend casting the return value of malloc():
* The cast is not required in ANSI C.
* Casting its return value can mask a failure to
#include <stdlib.h>, which leads to undefined behavior.

Nonsense!
Only inferior compiler fail to warn about
implicit declaration of function `malloc'

Perhaps, but there's no reason to depend on your compiler to issue
this (common but not universal) warning.

With the cast, if you forget to #include <stdlib.h>, you'll *probably*
get a warning about the call to malloc() with no visible prototype.
(gcc 3.3.3 doesn't give this warning by default; it does if you
specify "-Wall". Yes, you should always use "-Wall", but not everyone
does.)

Without the cast, if you forget to #include <stdlib.h>, you'll *almost
certainly* get an additional diagnostic about an implicit conversion
from type "int".

Although I know what you mean by "almost certainly", it's better to
explicitly point out that a compiler diagnostic is required by the C
standard in this case.
ERT attempts to refute Ben's second point, that the cast can mask a
failure to #include <stdlib.h>. But his first point, that the cast is
not required, is much stronger. Why use a cast when it's not needed?

The most reasonable answer was provided by P.J. Plauger: because the
paying customer wants to compile your code with a C++ compiler. Of
course, this doesn't justify the cast in other situations, not even when
the code needs to be used in a C++ program: it can be separately compiled
with a C compiler and linked with the other object files of the program.

Dan
 
D

Dan Pop

In said:
[snip]
With the cast, if you forget to #include <stdlib.h>, you'll *probably*
get a warning about the call to malloc() with no visible prototype. [snip]
Without the cast, if you forget to #include <stdlib.h>, you'll *almost
certainly* get an additional diagnostic about an implicit conversion
from type "int".

Only "almost certainly"? Isn't assignment of an int to a pointer a
constraint violation, which therefore requires a diganostic?

It does, but the diagnostic need not be about ``an implicit conversion
from type "int"''. The diagnostic could say "your code stinks" as far as
the standard is concerned and it could also be issued for translation
units that don't require any diagnostic, thus carrying zilch useful
information.

Getting a diagnostic about ``an implicit conversion from type "int"'' is
a quality of implementation issue, hence the "almost certainly" used by
Keith.

Dan
 
R

Richard Tobin

The most reasonable answer was provided by P.J. Plauger: because the
paying customer wants to compile your code with a C++ compiler.

Are there really C++ compilers that don't have a C mode for compiling
C files? If so, why do paying customers buy them?

-- Richard
 
M

Mark McIntyre

Only "almost certainly"? Isn't assignment of an int to a pointer a
constraint violation, which therefore requires a diganostic?

Perhaps, but AFAIR a compiler is only obligated to issue at least one
diagnostic. Code like this

int main(void)
int x = (long)12;
double *x = malloc(12);
}

might never get a diagnostic about the malloc call, having already issued
at least one.
 
K

Keith Thompson

Alex Fraser said:
[snip]
With the cast, if you forget to #include <stdlib.h>, you'll *probably*
get a warning about the call to malloc() with no visible prototype. [snip]
Without the cast, if you forget to #include <stdlib.h>, you'll *almost
certainly* get an additional diagnostic about an implicit conversion
from type "int".

Only "almost certainly"? Isn't assignment of an int to a pointer a
constraint violation, which therefore requires a diganostic?

You're right, it is. The "almost" was intended either to cover either
ancient non-conforming compilers or my own laziness in failing to take
the time to convince myself that a diagnostic is mandatory.

(Dan's comment that I was considering that the diagnostic doesn't have
to be meaningful is a good explanation, but I confess that it's not
what I had in mind.)
 
H

Herbert Rosenau

Hello,
I have a question regarding malloc and free.
Here my code sample:

int main() int main(void)
{
/* allocating dynamic memory for array */
int* array = (int*) malloc(5 * sizeof(int));

casting the result of an function returning a pointer to void invokes
undefined behavior as it hides the possible error that there is no
prototype of the function known to the compiler.
/* ... program code ... */

array = (int*) malloc(4 * sieof(int));

same as above.

this produces clearly a memory leak as the reference to the memoty
block allocated prior gets lost.
free(array);
}

Now my question: The second time I allocate
memory for array, what happens to the
address that I got with the first malloc?

It gets still lost - but the block itself lefts allocated, producing a
memory leak.
Is it freed automatically?

No.
 
H

Herbert Rosenau

Ben said:
cat main.c
int main(int argc, char* argv[]) {
// allocating dynamic memory for array
int* array = (int*)malloc(5*sizeof(int));

// ... program code ...

array = (int*)malloc(4*sizeof(int));// error: memory leak!

free(array);
return 0;
}
gcc -Wall -std=c99 -pedantic -o main main.c
main.c: In function `main':
main.c:3: warning: implicit declaration of function `malloc'
main.c:9: warning: implicit declaration of function `free'
I don't recommend casting the return value of malloc():

* The cast is not required in ANSI C.

* Casting its return value can mask a failure to
#include <stdlib.h>, which leads to undefined behavior.

Nonsense!
Only inferior compiler fail to warn about
implicit declaration of function `malloc'

Rubbish, there is nothing in the standard that requires an diagnostic
about that. The standard say only that an fuction that gets called
without prototype will return int. And int is somewhat different from
a pointer to any type that undefined behavior occures.

It is voluntary service to its customer when a compiler gives in one
of its options an ddiagnostic of 'missing prototype'. There is nothing
that can require that. Even gcc will NOT give that diagnostic - it may
give any diagnistic it likes - or even none. Casting from something to
something else is clearly the requirement to the compiler: "be quite -
I know what I do". But in that case you are lying to it as you clearly
NOT knows what you does. Kowing what you does would mean NEVER casting
a pointer to void to something else (what even ever) to avoid going
into the lands of undefined behavior.
 
H

Herbert Rosenau

[snip]
With the cast, if you forget to #include <stdlib.h>, you'll *probably*
get a warning about the call to malloc() with no visible prototype. [snip]
Without the cast, if you forget to #include <stdlib.h>, you'll *almost
certainly* get an additional diagnostic about an implicit conversion
from type "int".

Only "almost certainly"? Isn't assignment of an int to a pointer a
constraint violation, which therefore requires a diganostic?

An diagnostic is required, right. But there is nothing that requires
THIS text. It is on the compiler to cry instead "you are starting the
3. world wide war now" or "you are an idiot" or "please learn C before
you use this language". It may break the translation on that stage or
produce a binary
when the sun shines and none when it is april, it may give you any
time another text in the diagnostic anyway.
 
K

Keith Thompson

Herbert Rosenau said:
casting the result of an function returning a pointer to void invokes
undefined behavior as it hides the possible error that there is no
prototype of the function known to the compiler.

No, it doesn't invoke undefined behavior. Assuming a proper
"#include <stdlib.h>" (which the original program lacked), the
cast is merely useless.

It does invoke undefined behavior from the readers of comp.lang.c, but
that's outside the scope of the standard.
 
D

Dan Pop

In said:
about that. The standard say only that an fuction that gets called
without prototype will return int.

Nope, it doesn't. It returns whatever type was specified in its
declaration (which needs not be a prototype declaration). A function
called without a *declaration* in scope is implicitly declared as
returning int.

Dan
 
H

Herbert Rosenau

No, it doesn't invoke undefined behavior. Assuming a proper
"#include <stdlib.h>" (which the original program lacked), the
cast is merely useless.

It IS undefined behavior to convert an by malloc not used int variable
to a pointer. Ther is nothing that says that a function returnin void*
must set up the place the caller thinks a function returning int uses
as result. There is nothing that defines that a voud* has the same
size, alignment... as an int - so undefined behavior is invoked. Read
the standard!

The only case using a function that returns something unequal to int
is to use prototypes or other ways that lets the compiler _know_, not
assume the type of the value a function returns. Anything else IS
invoking undefined behavior. Clearly casting something the compiler
assumes instead of knowing is invokung the lands of undefined behavior
too.
It does invoke undefined behavior from the readers of comp.lang.c, but
that's outside the scope of the standard.
Rubbish. It is invoking undefining behavior in any case. Read the
standard.
 
H

Herbert Rosenau

Nope, it doesn't. It returns whatever type was specified in its
declaration (which needs not be a prototype declaration). A function
called without a *declaration* in scope is implicitly declared as
returning int.

Dan

From sight of the caller an unspecified function returns int - even as
the declaration that is outside the sight of the compiler at calling
point does something else. So the compiler uses the int it assumes the
calle had returned = undefined behavor.
 
L

Lawrence Kirby

Except in C99.
From sight of the caller an unspecified function returns int - even as
the declaration that is outside the sight of the compiler at calling
point does something else.

Which is what Dan said. It is different to what you said above because of
the distinction between the terms "declaration" and "prototype": you can
have a declaration in scope without having a prototype in scope. Prototypes
are the "new" function declaration and definition syntax that originated in
C++ and was introduced into C by the first, C89 standard.

long foo(); /* This is a declaration but not a prototype */
long foo(void); /* This is a declaration and a prototype */

long bar(x) long x; { return x; } /* This is a definition but not a prototype */
long bar(long x) { return x; } /* This is a definition and a prototype */

Definitions serve as declarations too.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,152
Latest member
LorettaGur
Top