How to free double ** memory

B

Ben

Hi,

If I allocate A like this:

A=(double **) malloc(sizeof(double *) * N);

Then I use A as a 2d array by assigning A[0] to A[N-1] to the
beginning of each row.

Will free(A) take the N elements back? There is no need to free the
memory pointed by A[0] to A[N-1].

Thanks,

Ben
 
J

jacob navia

Ben said:
Hi,

If I allocate A like this:

A=(double **) malloc(sizeof(double *) * N);

Then I use A as a 2d array by assigning A[0] to A[N-1] to the
beginning of each row.

Will free(A) take the N elements back? There is no need to free the
memory pointed by A[0] to A[N-1].

Thanks,

Ben

NO!!

You have to free each piece THEN free(A)
 
S

santosh

Ben said:
Hi,

If I allocate A like this:

A=(double **) malloc(sizeof(double *) * N);

The cast of return value of *alloc functions can hide errors. It's not
needed in C.

A = malloc(sizeof *A * N);

This form further has the benefit that if the type of *A changes, the
statement needs no editing.
Then I use A as a 2d array by assigning A[0] to A[N-1] to the
beginning of each row.

Will free(A) take the N elements back? There is no need to free the
memory pointed by A[0] to A[N-1].

No, you have to deallocate all the A[0] to A[N-1] vectors before handing A
over to free.

There should be one call to free for each call to *alloc. Further, free
should only be passed a value previously received from *alloc. Any other
value invokes undefined behaviour.

So:

for(ctr = 0; ctr < N; ctr++) free(A[ctr]);
free(A);
 
E

Eric Sosman

Ben wrote On 08/07/07 11:12,:
Hi,

If I allocate A like this:

A=(double **) malloc(sizeof(double *) * N);

Then I use A as a 2d array by assigning A[0] to A[N-1] to the
beginning of each row.

Will free(A) take the N elements back? There is no need to free the
memory pointed by A[0] to A[N-1].

free(A) will release the memory from the malloc(),
which is the memory A points to: the memory containing
A[0], A[1], ..., A[N-1].

free(A) will do nothing at all to the memory that
A[0] points to, nor A[1], ..., nor A[N-1].

Some other respondents have told you to free these
"second-level" memory chunks individually, but it's not
clear whether that's necessary, desirable, or even
possible. For instance, if the memory A[0] points to
was not obtained from malloc() or some such, it would
be an error to attempt to free() it. If all the second-
level memory was obtained in one malloc() call -- maybe
A[0] points to the beginning and A[1],...,A[N-1] point
to calculated offsets within it -- then free(A[0]) might
be correct but free(A[1]) would be wrong.
 
B

Ben

Ben said:
If I allocate A like this:
A=(double **) malloc(sizeof(double *) * N);

The cast of return value of *alloc functions can hide errors. It's not
needed in C.

A = malloc(sizeof *A * N);

This form further has the benefit that if the type of *A changes, the
statement needs no editing.
Then I use A as a 2d array by assigning A[0] to A[N-1] to the
beginning of each row.
Will free(A) take the N elements back? There is no need to free the
memory pointed by A[0] to A[N-1].

No, you have to deallocate all the A[0] to A[N-1] vectors before handing A
over to free.

There should be one call to free for each call to *alloc. Further, free
should only be passed a value previously received from *alloc. Any other
value invokes undefined behaviour.

So:

for(ctr = 0; ctr < N; ctr++) free(A[ctr]);
free(A);

If there is no need to free the 2d array pointed by A, do I still need
to free all rows pointed by A[0] to A[N-1]?

I clarify my question here.

A=(double **) malloc(sizeof(double *) * N);

Then, A[0] to A[N-1] are pointed to the rows of a 2d array B. A[j]
will point to the same position as B[j]. Now I want to free N
elements allocated by A, but don't want to deallocate the 2d array B.
Will free(A) take and only take the N elements back?

Thanks.
 
A

Army1987

A=(double **) malloc(sizeof(double *) * N);

Then, A[0] to A[N-1] are pointed to the rows of a 2d array B. A[j]
will point to the same position as B[j]. Now I want to free N
elements allocated by A, but don't want to deallocate the 2d array B.
Will free(A) take and only take the N elements back?

Thanks.

Yes. free() doesn't care about what you've written in memory
pointed by A.
 
S

SM Ryan

# Hi,
#
# If I allocate A like this:
#
# A=(double **) malloc(sizeof(double *) * N);
#
# Then I use A as a 2d array by assigning A[0] to A[N-1] to the
# beginning of each row.
#
# Will free(A) take the N elements back? There is no need to free the
# memory pointed by A[0] to A[N-1].

Roughly speaking, you have to match frees to mallocs (or callocs).
(More precisely, if you realloc a null, you have match the free
to the realloc, but if realloc modifies a pointer from a malloc,
then you match the original *alloc.) You only free *alloc pointers
and you only free them once. On program exit some systems free
unmatched *allocs, some systems don't.

Malloc and free don't know about arrays. They only know about
a block of bytes starting at some address for some number of bytes..
 
K

Keith Thompson

SM Ryan said:
Roughly speaking, you have to match frees to mallocs (or callocs).
(More precisely, if you realloc a null, you have match the free
to the realloc, but if realloc modifies a pointer from a malloc,
then you match the original *alloc.) You only free *alloc pointers
and you only free them once. On program exit some systems free
unmatched *allocs, some systems don't.
[...]

I think your statement about realloc() is a bit imprecise.

If you call realloc() with a null pointer as its first argument, it's
equivalent to calling malloc(), and you have to free the pointer that
was returned by realloc() (assuming it was non-null; if it was null,
you can free it or not, since free(NULL) does nothing).

If you call realloc() with a non-null pointer as its first argument,
the realloc() call can succeed or fail. If it succeeds, the pointer
you passed to it becomes invalid, and you need to free the pointer
returned by realloc(). If realloc() fails, the pointer you passed to
it is unchanged, and you need to free that pointer.

This implies that
ptr = ralloc(ptr, new_size);
is a bad idea, since it creates a memory leak if the realloc call
fails. (If your response to a realloc failure is going to be to abort
the program, it probably doesn't matter, but it's still a bad habit.)
 
W

William Hughes

The cast of return value of *alloc functions can hide errors. It's not
needed in C.
A = malloc(sizeof *A * N);
This form further has the benefit that if the type of *A changes, the
statement needs no editing.
Then I use A as a 2d array by assigning A[0] to A[N-1] to the
beginning of each row.
Will free(A) take the N elements back? There is no need to free the
memory pointed by A[0] to A[N-1].
No, you have to deallocate all the A[0] to A[N-1] vectors before handing A
over to free.
There should be one call to free for each call to *alloc. Further, free
should only be passed a value previously received from *alloc. Any other
value invokes undefined behaviour.

for(ctr = 0; ctr < N; ctr++) free(A[ctr]);
free(A);

If there is no need to free the 2d array pointed by A, do I still need
to free all rows pointed by A[0] to A[N-1]?

I clarify my question here.

A=(double **) malloc(sizeof(double *) * N);

Then, A[0] to A[N-1] are pointed to the rows of a 2d array B. A[j]
will point to the same position as B[j]. Now I want to free N
elements allocated by A, but don't want to deallocate the 2d array B.
Will free(A) take and only take the N elements back?

Thanks.



Yes.


free(A) will do nothing to the memory pointed to by
A[0], A[1], ..., A[N-1]. So if you want to release this
memory you have to call free(A[0]) (or whatever) etc. before you call
free(A) (after free(A) trying to get the contents of A[0]
may work, may work but get the wrong value, may cause
a segmentation fault, ...). However, if you dont
want to do anything to the memory pointed to by A[0],
A[1], ..., A[N-1] just call free(A). This will release
the memory resevered for the N elements of A.

- William Hughes
 

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,777
Messages
2,569,604
Members
45,220
Latest member
MathewSant

Latest Threads

Top