malloc and free

  • Thread starter Ramprasad A Padmanabhan
  • Start date
R

Ramprasad A Padmanabhan

Hello all,

If I assign one pointer to another , I had assumed I can call them
interchangably.

I can explain by the example below. I am doing a malloc to char* a which
is the same as char* b. But when I free(b) the memory allocated to a
does not get freed

Can someone explain this.
Thanks
Ram


main(){
char *a;
char *b;
a=b;

/* Call function which does a malloc */
foo(&a);

free(b) /* Is this ok , or should I do free(a) */


}

void foo( char **x){
*x = malloc(100);
return;
}
 
N

Nils Petter Vaskinn

Hello all,

If I assign one pointer to another , I had assumed I can call them
interchangably.

I can explain by the example below. I am doing a malloc to char* a which
is the same as char* b. But when I free(b) the memory allocated to a
does not get freed

Can someone explain this.
Thanks
Ram


main(){
char *a;

// what a points at now is undefined

// what b points at now is undefined

// a now points at the same undefined thing as b
/* Call function which does a malloc */
foo(&a);

// a now points at malloced memory
// b remains unchanged
free(b) /* Is this ok , or should I do free(a) */

// attempt freeing whatever undefined thing b points at
// boom
}

void foo( char **x){
*x = malloc(100);

// no error checking
 
D

Dan Pop

In said:
If I assign one pointer to another , I had assumed I can call them
interchangably.

I can explain by the example below. I am doing a malloc to char* a which
is the same as char* b. But when I free(b) the memory allocated to a
does not get freed

Can someone explain this.

main(){
char *a;
char *b;
a=b;

As b is still uninitialised, it is not a good idea to assign its value to
any other pointer.
/* Call function which does a malloc */
foo(&a);

free(b) /* Is this ok , or should I do free(a) */
}

void foo( char **x){
*x = malloc(100);

Where have you provided a declaration for malloc? It's not a function
returning int and the width of its parameter may not be the same as the
width of int. A compiler would actually complain about your program.
return;
}

You have a serious misconception about how C works. Let's try a simpler
example:

int i = 1;
int j = 2;

j = i;

At this point j has the same value as i, i.e. 1. Its old value is lost.

i = 0;

This affects the value of i, *only*. The value of j is unaffected, so
it's still 1.

Exactly the same thing happens to your program: after a = b both pointers
will contain the same garbage, when the foo function modifies a, the
value of b remains unaffected (still the same garbage as before). If you
want to have b synchronised with a, you need a

b = a;

*after* the foo() call. Now, you can pass *any* of them to free().
But any changes you make to one of them won't be reflected to the other.

OTOH, if you use one of them to change the pointed to object, the changes
will be visible trough the other pointer, as well (as long as both
pointers have the same value):

foo(&a);
if (a == NULL) return 0; /* the malloc call may fail */
b = a;
strcpy(a, "Hello world");
puts(b);
free(b);

will print "Hello world" to stdout and then the memory block will be
released by the free() call.

Dan
 
R

Robert B. Clark

If I assign one pointer to another , I had assumed I can call them
interchangably.

Yes, both pointers will point to the same object and may be dereferenced in
the same way.
I can explain by the example below. I am doing a malloc to char* a which
is the same as char* b. But when I free(b) the memory allocated to a
does not get freed


main(){
char *a;
char *b;
a=b;

Here, a == b.
/* Call function which does a malloc */
foo(&a);

Here, a == b is not guaranteed. Your foo() modifies the value of a, and a
no longer points to the same object as b.

Better, assign b = a after you've assigned a via malloc():

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

char *foo(void)
{
char *p;

if ((p = malloc(100)) != NULL)
*p = 'X';

return p;
}


int main( void )
{
char *a, *b;

/* Assign both a and b to malloced storage */

a = b = foo();

if (a != NULL)
{
printf("*a=%c\n", *a);
printf("*b=%c\n", *b);

free(b); /* Or free(a); a == b */
}

return 0;
}
 
S

Sunil Verma

Hello,

The problem you are facing is due to wrong assignment of values. You assign
value of 'b' to 'a' and then allocate 100 bytes. The address of this memory
is then assigned to 'a' (i.e. you have already lost the previous value
assigned to a). The right thing would be to allocate memory and then assign
the value stored in 'a' to 'b'. Now if you free(b), the memory allocated
will be freed. Something like this:

main()
{
char *a;
char *b;

foo ($a);
b = a;
free (b);
}

It is always a good idea to check if malloc was successful before
assignment. It eliminates various probable errors/issues you may run into if
memory allocation fails. Thought it is not applicable to the example below.

- Sunil Verma
 
G

goose

Ramprasad A Padmanabhan said:
Hello all,

If I assign one pointer to another , I had assumed I can call them
interchangably.

I can explain by the example below. I am doing a malloc to char* a which
is the same as char* b. But when I free(b) the memory allocated to a
does not get freed

Can someone explain this.

I'll try to; I'm going to ignore (for now) the fact that
your missed a header file and that "main ()" should be
"int main (void)" or "int main (int argc, char **argv)"
(or equivalent); I see that other posters have corrected
that and assume that you will follow their advice.

Also please note that in most C implementations, the
C programmer can not easily tell if a pointer is pointing
to valid memory (which was alloc()d in some way) or
invalid memory (memory which you cannot read and/or write
without nasty consequences). The implementation will also
not tell you which blocks of memory are available.

ok, we've got two pointers, and some memory; lets assume that
the following ascii diagram (you *are* using a fixed-width font,
right ?) represents the state of the machine at program startup.

in this machine of ours, we have only 200 "cells" of memory.
Pointers Memory available
cell_0 Y
cell_1 Y
cell_2 Y
cell_3 Y
...
cell_199 Y

when the program first starts up, we declare two pointers. now
remember that because we have not yet assigned them any values
(we have not made them point to anything), they could be pointing
/anywhere/. also remember that all those blocks of memory are
marked as "available". so after declaring the two pointers, our machine
now looks like this:

Pointers Memory available
cell_0 Y
cell_1 Y
a --> cell_2 Y
...
b --> cell_142 Y
...
cell_199 Y

like I said, they might be pointing anywhere. this means
that we should not try to read or write anything at the
memory they are pointing to because they might not be
pointing to a valid memory location (or "cell", in this
example). now we assign the value of pointer b to pointer
a, therefore a would be pointing to the same block of
memory as b. our machine is thus:

Pointers Memory available
cell_0 Y
cell_1 Y
cell_2 Y
...
a --> b --> cell_142 Y
...
cell_199 Y


in other words, they are both pointing to the same
bit of memory. now, we call malloc to *give* us
a chunk of memory that isn't being used by anyone
else, and we make b point to that chunk of memory
(which you wanted to be 100 "cells" wide).

so malloc looks through the memory cells, and decides
that since the memory from location 95 to 195 is not
being used, it gives us a /pointer/ to that, which we
assign to b. it *also* marks that memory as "not available".
machine looks like this after call to malloc:

Pointers Memory available
cell_0 Y
cell_1 Y
b --> cell_95 N
cell_96 N
...
a --> cell_142 N
...
cell_195 N
cell_196 Y
cell_197 Y
cell_198 Y
cell_199 Y

you see, malloc returned a pointer to
cell_95, and we assigned that pointer
to b, which is why b now points to
cell_95. unfortunately, we did not
reassign a to b, so a keeps its old
value (which was arbitrary to start with).

right, when we call free() with b as the argument,
free marks cell_95 - cell_195 as "available".

Pointers Memory available
cell_0 Y
cell_1 Y
b --> cell_95 Y
cell_96 Y
...
a --> cell_142 Y
...
cell_195 Y
cell_196 Y
cell_197 Y
cell_198 Y
cell_199 Y

so even though b and a are pointing *somewhere*,
we cannot store anything where they point, nor
can you read whatever it is that they are pointing
to. our pointers will almost certainly still be
pointing somewhere after we call free, but we may
not use a pointer which has been free()ed.

whew!
hth
goose,
implementations may differ, but thats all
 
G

goose

Sunil Verma said:

Hello there.

Welcome to CLC, please do not top-post, TIA.
some minor corrections follow below in your code.
The problem you are facing is due to wrong assignment of values. You assign
:q! /tmp/1.txt to 'a' and then allocate 100 bytes. The address of this memory
/tmp > is then assigned to 'a' (i.e. you have already lost the previous value
assigned to a). The right thing would be to allocate memory and then assign
the value stored in 'a' to 'b'. Now if you free(b), the memory allocated
will be freed. Something like this:

#include said:

/* this should be */
int main (void)
{
char *a;
char *b;

foo ($a);

/* 1. no prototype for foo
2. where did "$a" come from? do you mean &a ? */
foo (&a);
b = a;
free (b);

return 0;

/* you have also missed out the function foo(). this will possibly
result in a link error of some type. I've pasted the one
from the OP */

void foo( char **x){
*x = malloc(100);
return;
}

It is always a good idea to check if malloc was successful before
assignment.

before assignment to what? the pointer? it is always a good
idea to check the return value of *any* function. its a *very*
good idea to check the pointer returned by the memory allocation
functions before using any of them.

<snipped>

hand
goose,
 
S

Sunil Verma

Thanks Goose,

The main function was copied from intial post just to explain the necessary
assignment changes... assuming the author had run this programme he should
obviously have header file and function definition. Anyway thanks for your
time.
 

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,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top