Why cast to (char *) before de-allocating memory in "Numerical Recipes in C" ? 
Author Message
 Why cast to (char *) before de-allocating memory in "Numerical Recipes in C" ?

Hi,

The following code has been taken from Appendix B of the book
"Numerical Recipes in C". The code give a function to perform
the dynamic allocation of a matrix of double with row index
from 'nrl' to 'nrh' and column index from 'ncl' to 'nch' where
the number of rows = nrh - nrl + 1 and
the number of column = nch - ncl + 1.

This code performs very well and I did not encountered a problem with it;
however, I would like to have an explanation or the reason why in
the function to free the allocated memory, 'free_vector' below,
the authors "Numerical Recipes in C" choose to cast the pointers
to (char *) before the memory is de-allocated. Is this necessary ?

Thanks in advance for your help.

Note: The same is done for other numerical objects: vector of doubles,
vector of floats,
vector of integers, matrix of floats, matrix of integers, etc ...

double** dmatrix(int nrl, int nrh, int ncl, int nch)
 {
  int i,nrow,ncol;
  double** m;

  nrow = nrh - nrl + 1;
  ncol = nch - ncl + 1;

  m = (double **) malloc((size_t)((nrow+1)*sizeof(double*)));
  m += 1;
  m -= nrl;

  m[nrl] = (double *) malloc((size_t)((nrow*ncol+1)*sizeof(double)));
  m[nrl] += 1;
  m[nrl] -= ncl;

  for(i=nrl+1; i<=nrh;i++) m[i] = m[i-1] + ncol;

  return m;
 }

void free_dmatrix(double** m, int nrl,int ncl)
 {
   free((char*)(m[nrl]+ncl-1));
   free((char*)(m+nrl-1));
 }

--
Ren Girard

--



Wed, 11 Jan 2006 21:21:37 GMT  
 Why cast to (char *) before de-allocating memory in "Numerical Recipes in C" ?


Quote:

>The following code has been taken from Appendix B of the book
>"Numerical Recipes in C". The code give a function to perform
>the dynamic allocation of a matrix of double with row index
>from 'nrl' to 'nrh' and column index from 'ncl' to 'nch' where
>the number of rows = nrh - nrl + 1 and
>the number of column = nch - ncl + 1.

>This code performs very well and I did not encountered a problem with it;
>however, I would like to have an explanation or the reason why in
>the function to free the allocated memory, 'free_vector' below,
>the authors "Numerical Recipes in C" choose to cast the pointers
>to (char *) before the memory is de-allocated. Is this necessary ?

Have you read the IP restrictions placed on all the code in that book by
its authors? Certainly there most recent editions make it clear that you
are not allowed to even use the code on anything other than a single
designated machine (nor use programs you write on that machine on any
other machine) IMO the code in their books is unusable both because of
the horrible mechanistic translation from fortran and because of the
most draconian copyright restrictions I have ever seen.

--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
--



Thu, 12 Jan 2006 10:03:19 GMT  
 Why cast to (char *) before de-allocating memory in "Numerical Recipes in C" ?
[...]

Quote:
> why in
> the function to free the allocated memory, 'free_vector' below,
> the authors "Numerical Recipes in C" choose to cast the pointers
> to (char *) before the memory is de-allocated. Is this necessary ?

No.  Any platform where this *were* (still) necessary would have to be
called broken beyond all sensible repair, by today's standards.

That code is plain and simply bad C.  And it's not the only case of
such in that book, either.  Numerical Recipes was originally, and
effectively *still* is written in Fortran --- yes, even the version
whose cover claim it's "in C".  It's a prime example of the old saying
"real programmers can write Fortran in any language".

--

Even if all the snow were burnt, ashes would remain.
--



Thu, 12 Jan 2006 10:03:25 GMT  
 Why cast to (char *) before de-allocating memory in "Numerical Recipes in C" ?
Quote:

> Hi,

> The following code has been taken from Appendix B of the book
> "Numerical Recipes in C". The code give a function to perform
[-]
> This code performs very well and I did not encountered a problem with it;
> however, I would like to have an explanation or the reason why in
> the function to free the allocated memory, 'free_vector' below,
> the authors "Numerical Recipes in C" choose to cast the pointers
> to (char *) before the memory is de-allocated. Is this necessary ?
[-]
> void free_dmatrix(double** m, int nrl,int ncl)
>  {
>    free((char*)(m[nrl]+ncl-1));
>    free((char*)(m+nrl-1));
>  }

[-]
IMHO because pre-ansi compilers didn't use to know of generic void
pointers char* was used for generic pointers.

Now an implementation is free to implement pointers such that their
size varies depending on the type, say ...
sizeof(double*) != sizeof(int*) != sizeof(char*)
... is something quite possible and in such a case the result of
free()'d be, probably, desastrous.

With modern compilers that isn't a problem as free() is declared as
free(void*) and so any pointer is going to be casted to a void*
implicitly anyway.

Cheers,
Juergen

--
\ Real name     : Juergen Heinzl       \       no flames      /

--



Thu, 12 Jan 2006 10:03:28 GMT  
 Why cast to (char *) before de-allocating memory in "Numerical Recipes in C" ?

Quote:

> The following code has been taken from Appendix B of the book
> "Numerical Recipes in C".

It's horribly nonportable code to start with, relying on
pointer arithmetic well outside the range that is
guaranteed to work.

Quote:
> This code performs very well and I did not encountered a problem with it;

You may have been lucky, so far.

Quote:
> however, I would like to have an explanation or the reason why in
> the function to free the allocated memory, 'free_vector' below,
> the authors "Numerical Recipes in C" choose to cast the pointers
> to (char *) before the memory is de-allocated. Is this necessary ?

Both the cast of the argument to free and the cast of the
return value from malloc (which by the way should be
checked for a null pointer) indicate that the prototypes
for the free and malloc functions are not in scope.  Since
the example code indicates use of a version of C that
supports prototypes, and since the Standard C type for the
argument to free is (void *), that is further evidence
that the authors don't understand C programming.
--



Fri, 13 Jan 2006 08:36:24 GMT  
 Why cast to (char *) before de-allocating memory in "Numerical Recipes in C" ?
Thank you for your informative reply


Quote:

> > [...] I would like to have an explanation or the reason why in
> > the function to free the allocated memory, 'free_vector' below, the
> > authors "Numerical Recipes in C" choose to cast the pointers to (char *)
> > before the memory is de-allocated. Is this necessary ?

> > [...]

> > void free_dmatrix(double** m, int nrl,int ncl)
> >  {
> >    free((char*)(m[nrl]+ncl-1));
> >    free((char*)(m+nrl-1));
> >  }
> >  }
> >  }

> My guess is that the edition of the book
> you are using was written for an older
> C standard where this was required.
> --


--



Thu, 19 Jan 2006 11:50:09 GMT  
 Why cast to (char *) before de-allocating memory in "Numerical Recipes in C" ?
I did not reply earlier as we just returned from vacation.

Many thanks for the informative reply, especially the note on void * type of
pointer and the Web site address.

I would appreciate if you could give the address of the Web site at JPL on
the same topic.

Regards


Quote:
> _Numerical Recipes_ Caveats:

> <http://www.colorado.edu/ITS/docs/scientific/fortran/numrec.html>

> I had a better page on the same subject at JPL bookmarked, but I cannot
reach
> it at the moment. I do not know if that is because today is Saturday and
the
> page is in a *.gov domain or if it merely moved somewhere since I
bookmarked it
> years ago.

> Note: sometimes you cast to char * to give the compiler an increment size
when
> doing pointer arithmetic. void * itself has the storage size of
> a pointer, but it does not have an increment size when doing pointer
arithmetic
> on the
> value held by a void *. The compiler does not know what value "++(void
> *)varname" should have in relation to "(void *)varname".

> Compilers commonly assume that you want a
> sizeof(char) increment when they see this, but that is not specified in
the C89
> standard. I do not know whether the C99 standard has anything to say about
it.
> If you cast a variable to char *, on the other hand, then the compiler
knows to
> increment "++(char *)name" by "sizeof(char)".

> Good luck.

> Regards,

> Clayton Weaver

> "Everyone is ignorant, just about different things."  Will Rogers

--



Thu, 02 Feb 2006 12:44:39 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. char *ptr="Is memory allocated here?"

2. FS: "Numerical Recipes in C"

3. "Numerical Recipes in C" is nonport

4. "Numerical Recipes in C" is nonport

5. "Numerical Recipes in C" is nonport

6. \"Numerical Recipes\" in C

7. Need "Numerical Recipes in C"

8. "NUMERICAL RECIPES IN C" question

9. Reg.allocating memory for double char pointer(char ** buf)

10. Repeatedly Allocating/Deallocating Memory

11. Allocating/Deallocating Memory in a DLL and EXE causes Assertion-Error

12. Allocating/DeAllocating Memory associated to an array of structures

 

 
Powered by phpBB® Forum Software