Hi,
the meaning of NR_END is explained in pp. 940-941 of Numerical Recipes in C (2nd ed.):
2. Unit-offset vectors. In x1.2, we described how a unit-offset vector bb[1..4] could be
obtained from a zero-offset array b[0..3] by the pointer arithmetic operation bb=b-1. Since
bb points to one location before b, bb[1] addresses the same element as b[0], and so on.
Strictly speaking, this scheme is not blessed by the ANSI C standard. The problem
is not the fact that b-1 points to unallocated storage: location b-1 will never be referenced
without an increment back into the allocated region. Rather, the problem is that it might
happen in rare cases (and probably only on a segmented machine) that the expression b-1
has no representation at all. If this occurs, then there is no guarantee that the relation
b=(b-1)+1 is satisfied.
In practice, this is much less of a problem than one might think. We are not aware of
any compiler or machine on which b=(b-n)+n fails to be true for small integer n. Even on a
segmented machine, what typically happens is that the compiler stores some (perhaps illegal)
representation of b-n, andthat b is recoveredwhen n is added back to this representation. The
memory allocation routines in the First Edition of Numerical Recipes in C, in wide use since
1988, all have this “problem”, and we have had not even a single report of their failure in this
respect (notwithstanding the many readers who have told us that theoretically it could fail).
We have also communicated to standards bodies the desirability of blessing “b=(b-n)+n” (at
least for some range of n, say n representable as type short) in a future standard, since there
would seem to be no conflict with existing compilers in doing so.
Despite the absence of any experimental (as opposed to theoretical) problem, we have
taken some steps in this edition to make our vector and matrix allocation routines more ANSI
compliant. In the listing that follows, the parameter NR_END is used as a number of extra storage
locations allocated at the beginning of every vector or matrix block, simply for the purpose
of making offset pointer references guaranteed-representable. We set NR_END to a default
value of 1. This has the effect of making all unit-offset allocations (e.g., b=vector(1,7);
or a=matrix(1,128,1,128); ) be strictly ANSI compliant. With NR_END = 1, the number
of storage locations wasted is fairly negligible. Allocations with offsets other than 1 (e.g.,
b=vector(2,10)) are still theoretically non-compliant, but are virtually unknown in our
routines. If you need to make such allocations, you may wish to consider increasing the value
of NR_END (noting that larger values increase the amount of wasted storage).
The function allocates memory for an array v with suscripts ranging from nl to nh and returns a pointer to v[0] regardless of nl. In this way, &v is equivalent to (v+i) regardless of nl. It places an extra storage of NR_END variables at the beginning of the array.
WIth NR_END=1 it is intended to work on any machine for subscripts ranging from 0 (nl=0, as usual in C) or from 1 (nl=1, unit-offset vectors as used in Matlab for example).
Regards
Z
[/b]