Dynamic memory allocation and memory leak...

S

s.subbarayan

Dear all,
I happen to come across this exciting inspiring article regarding
memory leaks in this website:

http://www.embedded.com/story/OEG20020222S0026

In this article the author mentions:
"At a certain point in the code you may be unsure if a particular
block is no longer needed. If you free() this piece of memory, but
continue to access it (probably via a second pointer to the same
memory), your program may function perfectly until that particular
piece of memory is reallocated to another part of the program. Then
two different parts of the program will proceed to write over each
other's data. If you decide to not free the memory, on the grounds
that it may still be in use, then you may not get another opportunity
to free it (since all pointers to the block may have gone out of scope
or been reassigned to point elsewhere). In this case the program logic
will not be affected. But if the piece of code that leaks memory is
visited on a regular basis, the leak will tend towards infinity, as
the execution time of the program increases. "

I am not able to be clear on the second sentence:
"If you free() this piece of memory, but continue to access it
(probably via a second pointer to the same memory), your program may
function perfectly until that particular piece of memory is
reallocated to another part of the program."
I am also not able to get "the pointers to go out of scope" if I dont
free the memory as mentioned in the above paragraph?Can some one
enlight me on this?

My question is how can you free a memory and access it with second
pointer?My understanding was when I do malloc,I get exclusive access
to that piece of memory and unless I free it,its not available to some
one.If my understanding is correct,I dont see a way where a second
pointer can access it.I mean to say that my understanding is when
memory is allocated via malloc,the pointer returned is exclusively
accessing that place.How can some other pointer get a chance to point
to same location(unless the programmer explicitly comes to know the
address and assigns to a pointer)?

Even some time bak on MARCH 8th exactly,to my query on dynamic
allocation,some experts have voiced the same views said in this
article(google for "subbarayan" with in this group and u will get my
query).

It will be helpful if someone can make this clear to me so that I can
be careful while developing memory constraint applications.

Looking faward for all your replys and advanced thanks for the same,
Regards,
s.subbarayan
 
C

Christian Kandeler

s.subbarayan said:
My question is how can you free a memory and access it with second
pointer?

char *p1, *p2;
p1 = malloc(SOME_SIZE);
p2 = p1;
*p2 = 1; /* Okay. Access memory via p1; now *p1 and *p2 both hold the
value 1*/
*p2 = 2; /* Okay. Access memory via p2; now *p1 and *p2 both hold the
value 2 */
free(p1);
*p2 = 3; /* Bang! p2 is accessing memory that has been freed via p1 */
My understanding was when I do malloc,I get exclusive access
to that piece of memory and unless I free it,its not available to some
one.
True.

If my understanding is correct,I dont see a way where a second
pointer can access it.

If the second pointer belongs to you, then where's the problem?


Christian
 
C

Chris Croughton

Dear all,
I happen to come across this exciting inspiring article regarding
memory leaks in this website:

There shouldn't be memory leaks in websites, they will cause the server
to crash. Oh, sorry, that's not what you meant?
http://www.embedded.com/story/OEG20020222S0026

In this article the author mentions:
"At a certain point in the code you may be unsure if a particular
block is no longer needed. If you free() this piece of memory, but
continue to access it (probably via a second pointer to the same
memory), your program may function perfectly until that particular
piece of memory is reallocated to another part of the program. Then
two different parts of the program will proceed to write over each
other's data. If you decide to not free the memory, on the grounds
that it may still be in use, then you may not get another opportunity
to free it (since all pointers to the block may have gone out of scope
or been reassigned to point elsewhere). In this case the program logic
will not be affected. But if the piece of code that leaks memory is
visited on a regular basis, the leak will tend towards infinity, as
the execution time of the program increases. "
Yup.

I am not able to be clear on the second sentence:
"If you free() this piece of memory, but continue to access it
(probably via a second pointer to the same memory), your program may
function perfectly until that particular piece of memory is
reallocated to another part of the program."

...
char *p;
char *q;
...
p = malloc(size); /* p points to a memory area */
...
q = p; /* q points to the same memory */
...
free(p); /* memory is available for reallocation*/
...
*q = 5; /* q is still pointing at the freed memory */
I am also not able to get "the pointers to go out of scope" if I dont
free the memory as mentioned in the above paragraph?Can some one
enlight me on this?

void func(size_t size)
{
char *p = malloc(size);
...
}

The memory is still allocated, but the pointer to is is not now visible
anywhere so you can't free the memory.
My question is how can you free a memory and access it with second
pointer?My understanding was when I do malloc,I get exclusive access
to that piece of memory

What do you mean by "exclusive access"? Your program has exclusive
access to the memory, but as many pointers within that program as you
like can point at ait, as above.
and unless I free it,its not available to some
one.If my understanding is correct,I dont see a way where a second
pointer can access it.I mean to say that my understanding is when
memory is allocated via malloc,the pointer returned is exclusively
accessing that place.How can some other pointer get a chance to point
to same location(unless the programmer explicitly comes to know the
address and assigns to a pointer)?

I think you are confusing addresses (the memory area has a fixed
address, and malloc() can't reassign that memory, until it is freed) and
pointer variables. Pointer variables are just variables, you can assign
them to other pointer variables of the same type (or even of different
types with casting, although that is dangerous and generally
non-portable), add and subtract integers to them, etc.

It would be very unuseful if only one pointer at a time could point to a
particular memory location. For instance:

#include <stdio.h>
int getLine(char *buff, int length)
{
char *p = buff;
int c;
while (length-- > 0 && ((c = getchar()) != '\n')
*p++ = c;
*p = '\0';
return p - buff;
}

Chris C
 
T

Tor Rustad

I am not able to be clear on the second sentence:
"If you free() this piece of memory, but continue to access it
(probably via a second pointer to the same memory), your program may
function perfectly until that particular piece of memory is
reallocated to another part of the program."
I am also not able to get "the pointers to go out of scope" if I dont
free the memory as mentioned in the above paragraph?Can some one
enlight me on this?

char *p, *q;

p = q = malloc(10);
p += 11; /* <-- out of scope */

or

p = malloc(10);
q = realloc(p, 15);
printf("p = 0x%p\nq = 0x%p\n", (void *)p,(void *)q);

where 'p' and 'q' might not be pointing at the same mem chunk anymore,
so

*p = 0;

is UB.
My question is how can you free a memory and access it with second
pointer?

easy

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

int main(void)
{
char *p, *q;

p = q = malloc(10);

strcpy(p, "Alloced!");
printf("p = 0x%p\nq = 0x%p\nContent of 'q': %s\n", (void *)p,(void
*)q, q);

free(p);
printf("p = 0x%p\nq = 0x%p\n", (void *)p,(void *)q);
}

My understanding was when I do malloc,I get exclusive access
to that piece of memory and unless I free it,

In the code above, 'p' and 'q' point to the _same_ malloc'ed object, but
after the free() call,
dereferencing 'p' or 'q' is UB.
 
E

Eric Sosman

Tor said:
s.subbarayan said:
[...]
I am also not able to get "the pointers to go out of scope" if I dont
free the memory as mentioned in the above paragraph?Can some one
enlight me on this?

char *p, *q;

p = q = malloc(10);
p += 11; /* <-- out of scope */

No; `p' is still in scope. The calculation attempts to
produce a value that is out of *range*, but "scope" is a
different matter altogether.

The "scope" question was about
>>In this article the author mentions:
>>"[...] If you decide to not free the memory, on the grounds
>>that it may still be in use, then you may not get another opportunity
>>to free it (since all pointers to the block may have gone out of scope
>>or been reassigned to point elsewhere). [...]"

.... and the explanation is something like this: In the
silly and stupid function

void f(void) {
char *p = malloc(10);
}

.... a variable named `p' is created when f() is called,
and that variable vanishes when f() returns. Once `p'
vanishes it is gone forever and can never be used again;
the next time f() is called a brand-new `p' will be created,
completely unrelated to the first `p' and to any other `p's
that may be created by further calls to f().

The consequence is that each call to f() leaks memory.
The memory is "leaked" because after f() returns there is no
way to recover the value that was in the now-vanished `p'.
The only way to make use of the memory is with that pointer
value (or with other pointer values derived from it), and
since the value is no longer available there is no way to
use the memory. The only way to release the memory is to
pass the pointer value to free() or realloc(), and since the
value is no longer available this cannot be done. Result:
a piece of memory that can neither be used nor released;
this is what is meant by "leaked" memory.

<pedantry>

"Going out of scope" is really not the correct way to
describe this scenario. Scope is a lexical concept, not a
dynamic concept, and a variable does not necessarily vanish
and lose its value when it goes out of scope. Here is a
function that does not leak memory:

void g(void) {
static char *p = NULL;
if (p == NULL)
p = malloc(10);
}

The scope of `p' ends at the closing `}' of the function g(),
yet `p' retains its value even while the program is executing
in other scopes. Also, there is only one `p' created no matter
how many times g() is called; every invocation of g() refers to
the same `p' as every other.

Despite its inexactness, "going out of scope" is accepted
slang for "ending the storage duration." The two are identical
for variables of `auto' or `register' class, so the inexact
slang is "close enough for jazz" much of the time.

</pedantry>
 
T

Tor Rustad

Eric Sosman said:
Tor said:
s.subbarayan said:
[...]
I am also not able to get "the pointers to go out of scope" if I dont
free the memory as mentioned in the above paragraph?Can some one
enlight me on this?

char *p, *q;

p = q = malloc(10);
p += 11; /* <-- out of scope */

No; `p' is still in scope. The calculation attempts to
produce a value that is out of *range*, but "scope" is a
different matter altogether.

Thanks for the correction! I am still not sure what OP
didn't understand, some of the questions indicated
that the problem was understanding how pointers
work.
 
S

s.subbarayan

Eric,
Thanks for your effort in clearing me the cause of leakage and
explaination whats meant by out of scope.Its really superb!I am happy
about the way you explained me!
So in the function mentioned by you,I mean using malloc inside a
function,which causes leakage(I am talking abt the one which does not
have scope identifier "static" for the pointer which points to
allocated memory using malloc)I believe had I used free() inside the
function itself,this leakage would have been avoided.I would be clear
if what I understood is correct.
Please confirm whether what I understood is correct.

PS:MR.Tor,Regarding your question of what I did not understand
correct,is
"Actually after going through Eric's reply only I was clear that
pointers accessing memory through malloc inside a function does not
have global scope.I was in a doubt about it when I posted it,for which
Eric has provided excellent explaination"
I thank you for your efforts in making me understand this Tor.

Regards,
s.subbarayan
 
E

Eric Sosman

s.subbarayan said:
[...]
So in the function mentioned by you,I mean using malloc inside a
function,which causes leakage(I am talking abt the one which does not
have scope identifier "static" for the pointer which points to
allocated memory using malloc)I believe had I used free() inside the
function itself,this leakage would have been avoided.I would be clear
if what I understood is correct.
Please confirm whether what I understood is correct.

If the functions had called free() for each pointer
returned from malloc(), no memory would have been leaked.
That much is true.

However, a function that allocates memory but does
not free it does not necessarily leak that memory. Take
malloc() itself as an example: it allocates but does not
release, yet in and of itself it leaks no memory. What
is the secret?

The important thing is that a pointer to the allocated
memory survives after malloc() returns -- because malloc()
passes that pointer back to the caller. The caller can use
the pointer to access the memory and perhaps to free() it
sometime later; memory that is accessible is not leaked.

The case is similar for other functions you might write:
if the function calls malloc() and returns the pointer to
its own caller, or stores it in a global variable, or adds
the new memory to a linked list, or in any other way assures
the survival of the pointer value, the memory is not leaked.
As long as the pointer value remains accessible to the program,
the memory itself remains accessible and is not leaked.

However, "leak" is an inexact term, a sort of slang, and
different people will use it in different ways. For example,
it is possible that the program retains a valid pointer to
the allocated memory but never uses the pointer: the memory
is accessible in principle, but not in actuality. Some people
call this situation a "memory leak," too, while others will
say it is not a leak but an "inefficient use" of memory.

Whenever you allocate dynamic memory, think about the
lifetime of that memory and think about who has the job of
releasing it. If it's going to be released by the same function
that allocated it, study the function carefully to be sure it
*always* performs the release. If it's going to be released
by some other function, make sure this is made clear in the
first function's "contract," and study that function's callers
to make sure they obey the contract.
 
G

Guillaume

Well, to each their own definition I guess, as you said...
As for me, I consider that anytime some chunk of dynamically
allocated memory continues to exist after it's not needed
anymore, there is a memory leak. Simple as that.
 
S

s.subbarayan

Eric,
I infer from your mail about memory leak as follows:
In the same function which was allocating memory even though I use a
local pointer variable to point to the malloced memory,if I create one
more global pointer variable of the same type as local variable one
and the store the value of local inside global I understand I will be
able to access that memory until some on else change the value of
global pointer.

code:

int *p;
void main()
{
int *q;
q=malloc(sizeof(int));
p=q;
}
Which means later I will be able to free(p) provided q does not
require it any more and p's value does not get changed before I free
it.Is this correct?


So One thing clear to me is as long as you are able to access the
memory allocated dynamically by a pointer which is alive,you still
have chance to free it which means you are avoiding memory leaks.
I believe I have got it right from what you have said.
Please let me know incase my understanding is wrong.

Thanks for your reply and looking farward for your comments,

Regards,
s.subbarayan
 
E

Eric Sosman

s.subbarayan said:
[...]
So One thing clear to me is as long as you are able to access the
memory allocated dynamically by a pointer which is alive,you still
have chance to free it which means you are avoiding memory leaks.
I believe I have got it right from what you have said.
Please let me know incase my understanding is wrong.

You seem to understand correctly. As long as the
program retains a pointer to the allocated memory, the
memory remains accessible and can be used or released
(via that retained pointer value). If the memory remains
allocated but the program "forgets" the pointer value,
the memory becomes inaccessible and un-releasable (because
you no longer have the pointer); this is "leaked memory."

The question of whether the memory is being used
wisely and well is a separate issue. "Guillaume" (see
up-thread) thinks memory that's allocated and accessible
but not actually used is "leaked," but that's not the term
I myself would use. We can both be right (or wrong), though,
because "memory leak" is not defined by any standard -- at
least, not by any standard I've ever heard of.
 

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,961
Messages
2,570,131
Members
46,689
Latest member
liammiller

Latest Threads

Top