free() is useless...

M

Matt Gostick

Well, it's not useless, it just doesn't seem to be working for me.

Basically, when I'm returning a pointer from a function, free does not
seem to be freeing the memory for me. Here is an example of what I am
trying to do:

char *blah (void) {
char *string;

string = (char *) malloc(sizeof("foobar")*sizeof(char));
strcpy(string, "foobar");

return string;
}

int main (void) {
char *string;

string = blah();
printf("%s\n", string);
free(string);

return 0;
}


-----

I'm not quite sure how to properly diagnose this... as I haven't
touched C in quite some time. Although, the problem I am having now
is evident b/c the software is a high volume socket server and I can
see the process size growing with `top`.

Any help would be very much appretiated.
Thanks,
Matt.
 
R

Ravi Uday

Matt Gostick said:
Well, it's not useless, it just doesn't seem to be working for me.

Basically, when I'm returning a pointer from a function, free does not
seem to be freeing the memory for me.

How can you say that it is not freeing the memory. If you are referring to
contents before free
and after 'free' and finding it to be same then, that is normal - your
implementation/OS can do
anything with the memory once you call 'free'.
Here is an example of what I am
trying to do:
Include standard headers first..

#include <stdio.h>
#include said:
char *blah (void) {
char *string;

string = (char *) malloc(sizeof("foobar")*sizeof(char));

No need to cast the return value of malloc.

string = malloc(sizeof("foobar")*sizeof *string );
strcpy(string, "foobar");

return string;
}

int main (void) {
char *string;

Hey why are you defining 'string' here ?
Dont you see a name conflict when inside 'blah' function ?
Pass it as a parameter instead.
 
W

William L. Bahn

Ravi Uday said:
How can you say that it is not freeing the memory. If you are referring to
contents before free
and after 'free' and finding it to be same then, that is normal - your
implementation/OS can do
anything with the memory once you call 'free'.

I think he was pretty explicit on what the symptoms are that are
telling him that the memory may not be getting freed properly.
Include standard headers first..

#include <stdio.h>


No need to cast the return value of malloc.

Unless your compiler, like mine, would throw the following error
(not warning):

Compiling JUNKER.C:
Error JUNKER.C 19: Cannot convert 'void *' to 'char *' in
function main()

And that's when it is configured for ANSI compliance
string = malloc(sizeof("foobar")*sizeof *string );


Hey why are you defining 'string' here ?
Dont you see a name conflict when inside 'blah' function ?

Why? I'll bet a lot of other people in the world have the same
basic phone number you do - is there a name conflict? Or do
things like area codes and country codes resolve them? How does
the person writing main() or any other function tell what the
internal names are within other functions - in general?
Pass it as a parameter instead.

In which case he would still have to call it something - and the
name string is just as good as any other - and pass it by
reference. Why add the complexity when it's not needed?
 
F

Flash Gordon

Unless your compiler, like mine, would throw the following error
(not warning):

Compiling JUNKER.C:
Error JUNKER.C 19: Cannot convert 'void *' to 'char *' in
function main()

And that's when it is configured for ANSI compliance

<snip>

That probably means you are invoking it as an ANSI C++ compiler instead
of an ANSI C compiler. The implicit conversion is part of the ANSI/ISO
standard so an ANSI/ISO C compiler that rejects it is faulty. Even
giving a warning on it would, IMHO, be a sign of a poor implementation
unless you used an option to explicitly enable such a silly thing.
 
G

Goran Larsson

William L. Bahn said:
Compiling JUNKER.C:
Error JUNKER.C 19: Cannot convert 'void *' to 'char *' in
function main()

And that's when it is configured for ANSI compliance

Your C compiler is broken, or you are using a C++ compiler to
compile C code.
 
M

Martin Ambuhl

William said:
Unless your compiler, like mine, would throw the following error
(not warning):

Compiling JUNKER.C:
Error JUNKER.C 19: Cannot convert 'void *' to 'char *' in
function main()

And that's when it is configured for ANSI compliance

Your compiler is broken or else you are invoking it for ANSI C++
compliance, not ANSI C compliance.
 
A

Alberto =?iso-8859-1?Q?Gim=E9nez?=

El Thu, 2 Sep 2004 12:00:25 +0530, Ravi Uday escribió:
string = malloc(sizeof("foobar")*sizeof *string );

I think it will suffice:

string = malloc(sizeof("foobar"));
if (string == NULL)
/* error handling */
Hey why are you defining 'string' here ?
Dont you see a name conflict when inside 'blah' function ?

No. Blah's 'string' is completely different to main's 'string', and
there is no confusion possible, except por a human.
Pass it as a parameter instead.
Why?

return EXIT_SUCCESS :)

<OT>
there are several tools to diagnose memory leaks and access violations.
If you are using GNU glibc, you can modify original malloc behaviour so
i can tell you if you are not freeing memory or trying to free not
malloc'd memory.
<OT>
 
C

CBFalconer

Ravi Uday wrote:
Matt Gostick said:
.... snip ...

#include <stdio.h>


No need to cast the return value of malloc.

string = malloc(sizeof("foobar")*sizeof *string );


Hey why are you defining 'string' here ?
Dont you see a name conflict when inside 'blah' function ?
Pass it as a parameter instead.

Nonsense. Nothing wrong with that except use of the reserved id
'string'. And even that may not be so for function scope, not
sure.
 
R

Richard Tobin

Matt Gostick said:
Basically, when I'm returning a pointer from a function, free does not
seem to be freeing the memory for me. Here is an example of what I am
trying to do:

It looks OK (modulo missing headers).
I'm not quite sure how to properly diagnose this... as I haven't
touched C in quite some time. Although, the problem I am having now
is evident b/c the software is a high volume socket server and I can
see the process size growing with `top`.

So evidently the *real* code is something different, which differs
from the example in some relevant way. We can't diagnose it like that...

I suggest finding a debugging malloc library for your platform.
Sometimes the standard malloc has options you can set (e.g. by a
function call or environment variables) to trace mallocs and frees.
Or maybe your debugger has memory leak checking available (like dbx on
Solaris).

If all else fails, replace your calls to malloc and free with calls to
"my_malloc" and "my_free" and write those functions to log everything.
This won't work if the leak is in some other library function that calls
malloc, of course.

By the way, this is pointless:
string = (char *) malloc(sizeof("foobar")*sizeof(char));

sizeof("foobar") already takes account of the size of char, so your
calculation is only right because sizeof(char) is always 1.

-- Richard
 
V

Villy Kruse

I think he was pretty explicit on what the symptoms are that are
telling him that the memory may not be getting freed properly.


Try in a loop malloc for example 2 Meg and free it again.
Then run the same loop without free. I would expect the
effect of free to become quite obvious.

On quite a few systems you realy can't tell if free has
freed memory until you need the memory to malloc another block.


Villy
 
T

tristan

Matt said:
Well, it's not useless, it just doesn't seem to be working for me.

Basically, when I'm returning a pointer from a function, free does not
seem to be freeing the memory for me. Here is an example of what I am
trying to do:

char *blah (void) {
char *string;

string = (char *) malloc(sizeof("foobar")*sizeof(char));
strcpy(string, "foobar");

return string;
}

Don't bother multiplying by sizeof(char), as it is 1 by definition.
Don't cast malloc().
Do #include <stdlib.h>.
Don't request too little memory, and then overrun the buffer, as this
will tend to trash the malloc arena and cause it to misbehave.

More specifically:

#include <stdlib.h>
#include <string.h>

char *blah_1 (void) {
char *buf;
char foobar[] = "foobar";
size_t size;

/* the size of a buffer that can contain "foobar" */
size = sizeof foobar;

buf = malloc(size);
strcpy(buf, foobar);

return buf;
}

char *blah_2 (void) {
char *buf;
size_t size;

/* the length of "foobar" and its end marker */
size = strlen("foobar") + 1;

buf = malloc(size);
strcpy(buf, "foobar");

return buf;
}

char *blah_3 (void) {
char *buf;
size_t size;

/* the size of a pointer variable! */
size = sizeof("foobar");

buf = malloc(size);
/* overflows unless sizeof(char *) >= 7 */
strcpy(buf, "foobar");

return buf;
}


Tristan
 
R

Richard Tobin

Eric Sosman said:
This is Question 7.25 in the comp.lang.c Frequently
Asked Questions (FAQ) list

I don't think so. The OP's problem is that memory use keeps rising
despite freeing memory. The FAQ is about memory not going down.

More likely there is a bug in the program.

-- Richard
 
K

Keith Thompson

William L. Bahn said:
Unless your compiler, like mine, would throw the following error
(not warning):

Compiling JUNKER.C:
Error JUNKER.C 19: Cannot convert 'void *' to 'char *' in
function main()

And that's when it is configured for ANSI compliance

ANSI *what* compliance?

Some compilers assume that a source file suffix of ".C" implies C++,
and ".c" implies C. Change the name from "JUNKER.C" to "junker.c" and
try again.
 
M

Matthew Fisher

Well, it's not useless, it just doesn't seem to be working for me.

Basically, when I'm returning a pointer from a function, free does not
seem to be freeing the memory for me. Here is an example of what I am
trying to do:

char *blah (void) {
char *string;

string = (char *) malloc(sizeof("foobar")*sizeof(char));

The above line has a bug in that the buffer is one byte too short.
You are lucky however since malloc generally returns a minimum of 8
bytes. Contradicting some other posters, you should cast. You don't
need the second sizeof() since malloc takes a number of bytes and
sizeof returns bytes.
strcpy(string, "foobar");

return string;
}

int main (void) {
char *string;

string = blah();
printf("%s\n", string);
free(string);

return 0;
}

The above snippet does not appear to leak. If you put it in a loop
and let it run, the process memory size will not grow. You actual
case must be different.

What operating system are you using? There are a variety of memory
leak checking tools available some are free. Check out Valgrind if
you are Linux. Also check out mpatrol, it is widely ported and is
free.

Dynamic Memory Solutions (my company) sells Dynamic Leak Check for
Solaris and Linux. It checks for memory leaks and a variety of other
errors, www.dynamic-memory.com.

good luck,
Matthew
 
W

William L. Bahn

Keith Thompson said:
ANSI *what* compliance?

Some compilers assume that a source file suffix of ".C" implies C++,
and ".c" implies C. Change the name from "JUNKER.C" to "junker.c" and
try again.

FWIW - the compiler is Borland TurboC/C++ v4.5,

The compiler always prints the file names in all uppercase.

The filename is all lower case - and, being a DOS/Windows
implementation, the user doesn't have very good control over case
in filenames anyway.

I'm pretty sure that it uses *.c for C files and *.cpp. If you
save it using the compiler supplied filename (and hence a *.cpp
extension) then you definitely get different compile behavior for
certain things.

Also, with configured for ANSI (and that's the entire label on
the option in the dialog box) it will not permit end-of-line
comments.
 
W

William L. Bahn

Keith Thompson said:
"return 0;" and "return EXIT_SUCCESS;" are equally valid.

But are they the same?

I know what value "return 0;" will return. What value will
"return EXIT_SUCCESS;" return?
 
M

Mabden

William L. Bahn said:
But are they the same?

I know what value "return 0;" will return. What value will
"return EXIT_SUCCESS;" return?

I want to say, whatever EXIT_SUCCESS is defined as... Or is that too
obvious?

Programmers tend to use zero as a success and other numbers are errors
because there are more ways for something to go wrong than to go right.
 

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
474,146
Messages
2,570,832
Members
47,374
Latest member
anuragag27

Latest Threads

Top