Will this leak memory?

J

Joakim Hove

Hello,

I have the following code:

foo_ptr * alloc_foo(int size, ...) {
/*
This function allocates an instance of the foo_ptr type,
and returns a pointer to the newly allocated storage.
*/
}

void free_foo(foo_ptr *foo) {
....
}

void func(const foo_ptr *foo) {
/*
Do something (read-only) on the foo object.
*/
}


int main(void) {

func( alloc_foo(10 , ...) );

}

Now my question is wether the memory set aside by alloc_foo() will
leak. Since I have not stored a pointer to this memory I can not free
it myself. If this will indeed leak memory I will have to do it like
this:

{
foo_ptr *tmp_foo = foo_alloc(10 , ...);
func(tmp_foo);
free_foo(tmp_foo);
}

Which is considerably less elegant.

Best regards

Joakim
 
S

santosh

Joakim said:
Hello,

I have the following code:

foo_ptr * alloc_foo(int size, ...) {
/*
This function allocates an instance of the foo_ptr type,
and returns a pointer to the newly allocated storage.
*/
}

void free_foo(foo_ptr *foo) {
....
}

void func(const foo_ptr *foo) {
/*
Do something (read-only) on the foo object.
*/
}


int main(void) {

func( alloc_foo(10 , ...) );

}

Now my question is wether the memory set aside by alloc_foo() will
leak. Since I have not stored a pointer to this memory I can not free
it myself. [ ... ]

Yes, unless, func itself calls free_foo.
If this will indeed leak memory I will have to do it like this:

{
foo_ptr *tmp_foo = foo_alloc(10 , ...);
func(tmp_foo);
free_foo(tmp_foo);
}

Which is considerably less elegant.

Maybe. You can also wrap one or more of those operations together,
depending on what exactly your code does. In any case, correctness is
more important than readability.
 
D

Duncan Muirhead

On Thu, 08 Mar 2007 04:06:32 -0800, Joakim Hove wrote:
void func(const foo_ptr *foo) {
int main(void) {

func( alloc_foo(10 , ...) );

}
<snip>

If you're really just calling foo once and exiting, then
there's no leak. If however you call func as above often,
there is a leak. You could could avoid this with "elegant"
(some might say terse) code by having func return its argument,
and writing free_foo( func( alloc_foo(..)));
However foo_ptr* free_foo( const foo_ptr * foo) is a bit awkward:
you'll get a warning about discarding the qualifier when you return
foo (although you could be vile and cast the warning away), so you
might have to give up the const.

Duncan
 
F

Franchie

Hello,

I have the following code:

foo_ptr * alloc_foo(int size, ...) {
/*
This function allocates an instance of the foo_ptr type,
and returns a pointer to the newly allocated storage.
*/

}

void free_foo(foo_ptr *foo) {
....

}

void func(const foo_ptr *foo) {
/*
Do something (read-only) on the foo object.
*/

}

int main(void) {

func( alloc_foo(10 , ...) );

}

Now my question is wether the memory set aside by alloc_foo() will
leak. Since I have not stored a pointer to this memory I can not free
it myself. If this will indeed leak memory I will have to do it like
this:

{
foo_ptr *tmp_foo = foo_alloc(10 , ...);
func(tmp_foo);
free_foo(tmp_foo);

}

Which is considerably less elegant.

Best regards

Joakim

As it stands, this will leak memory, as you never free it.
Maybe you can make func return the pointer, so that you can use it
like this:

free(func(alloc()));

However, maybe the line is now getting too long to be considered
elegant...

You could also use a GC, but I frankly believe that it is overkill,
and somehow makes you think more of C++ than C. [shudders].

F.
 
R

Richard Bos

Joakim Hove said:
foo_ptr * alloc_foo(int size, ...) {
/*
This function allocates an instance of the foo_ptr type,
and returns a pointer to the newly allocated storage.
*/
}
int main(void) {

func( alloc_foo(10 , ...) );

}

Now my question is wether the memory set aside by alloc_foo() will
leak.

That depends on how alloc_foo() allocates its memory. The way you call
it, it usually will leak. If alloc_foo() is, for example, just a wrapper
around malloc(), then yes, that's a memory leak.
Since I have not stored a pointer to this memory I can not free
it myself. If this will indeed leak memory I will have to do it like
this:

{
foo_ptr *tmp_foo = foo_alloc(10 , ...);
func(tmp_foo);
free_foo(tmp_foo);
}

Which is considerably less elegant.

But correct.

Richard
 
J

Joakim Hove

That depends on how alloc_foo() allocates its memory. The way you call
it, it usually will leak. If alloc_foo() is, for example, just a wrapper
around malloc(), then yes, that's a memory leak.

Well - yes it is a wrapper around malloc.
But correct.

Well - I will stick with correct.

Thank you too all who found time to answer; I guess the question was a
bit like wishfull thinking on my behalf, I was expecting it would
leak. The reason I asked at all is that you can write things
resembling this code (at least in C99):

some_func(const int *int_ptr) { }

int main (void) {
....
some_func((const int *) {1 , 2 , 3 , 4});
....
}

Without a leak?

Anyway - I will stick with my less elegant and correct solution.

Regards

Joakim
 
R

Roland Pibinger

I will have to do it like this:
{
foo_ptr *tmp_foo = foo_alloc(10 , ...);
func(tmp_foo);
free_foo(tmp_foo);
}

Which is considerably less elegant.

On the contrary. The above solution implements a common C idiom:
allocate/use/de-allocate or open/use/close (compare e.g.
fopen/fread/fclose). OTOH, your original solution is quite inelegant.

Best wishes,
Roland Pibinger
 
C

Chris Dollin

Roland said:
On the contrary. The above solution implements a common C idiom:
allocate/use/de-allocate or open/use/close (compare e.g.
fopen/fread/fclose). OTOH, your original solution is quite inelegant.

I though the OP's original code was /elegant/, but leaked memory.

It would be nice if C had an expression that evaluated to a local
array, but (a) C++ shows us that picking a useful lifetime for
that object is not non-contentious and (b) there are a great many
things that it would be nice for C to have, one of which is not
having a great many things.

Bring back `aptovec`, that's what I say. (But not very loudly.)
 
B

Bill Pursell

"Joakim Hove" wrote (well, almost,
I removed some whitespace and comments for
clarity):
I have the following code:

foo_ptr * alloc_foo(int size, ...) { }

That first argument should probably be
of type size_t.
void free_foo(foo_ptr *foo) { }
void func(const foo_ptr *foo) { }

int main(void) {
func( alloc_foo(10 , ...) );
}

Now my question is wether the memory set
aside by alloc_foo() will leak.

I see 2 clean alternatives:
1) have func call free(foo). This will
mean you have to drop the 'const' qualifier
in the declaration of func.
2) (My preferred solution)
int
main(void)
{
void *f;

func( f = alloc_foo( SIZE ));
free_foo( f );
}
 
D

David Thompson

Thank you too all who found time to answer; I guess the question was a
bit like wishfull thinking on my behalf, I was expecting it would
leak. The reason I asked at all is that you can write things
resembling this code (at least in C99):

some_func(const int *int_ptr) { }

int main (void) {
....
some_func((const int *) {1 , 2 , 3 , 4});
....

Not quite. (const int []) {1,2,3,4}, which decays to a const int *
value which can be passed to some_func. Or if you want to be grossly
explicit (const int *) (const int []) {1,2,3,4}
}

Without a leak?
Yes. A compound literal in block scope without the 'static' qualifier
has automatic lifetime and thus is cleaned up automatically.
 

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

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,690
Latest member
MacGyver

Latest Threads

Top