Continue to Site

Welcome to

Welcome to our site! is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

C++ question! - help with malloc, code understanding

Not open for further replies.


Junior Member level 1
Mar 31, 2003
Reaction score
Trophy points
Activity points
The code is from Numerical Recipes book. The thing I didn't understand is the line "return v-nl+NR_END;". As far as I know malloc returns the point to the storage allocated. Can anyone explain me this.

float *vector(long nl, long nh)
/* allocate a float vector with subscript range v[nl..nh] */
float *v;

v=(float *)malloc((size_t) ((nh-nl+1+NR_END)*sizeof(float)));
if (!v) nrerror("allocation failure in vector()");
return v-nl+NR_END;


What is NR_END?



#define NR_END 1

NR_END is "just in case" in order to not return 0



I have tryed di this (nh =10 and nl = 5):

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

void main(void){

float *v, *paux;

v=(float *)malloc((size_t) ((10-5+1+1)*sizeof(float)));

paux= v-5+1;



Runing it with Ration Purify it tells:

[E] ABW: Array bounds write in main {1 occurrence}
Writing 4 bytes to 0x01331980 (4 bytes at 0x01331980 illegal)
Address 0x01331980 is 16 bytes before the beginning of a 28 byte block at 0x01331990
Address 0x01331980 points to a malloc'd block
Thread ID: 0x5b4
Error location
main [teste.c:16]
//paux= v;
paux= v-5+1;

=> *paux=1.0;

mainCRTStartup [crt0.c:206]
Allocation location
malloc [dbgheap.c:129]
main [teste.c:11]
mainCRTStartup [crt0.c:206]

So, I think this are wrong, or the code that use the function will incremente the pointer of nl.


it is a simple memory vecter allocator NR-end is the origin of the end of that rountine

dont forget too include the correct header and also the lib

I know that code is a simple vector memory storage allocator. But I didn't understand the line "return v-nl+NR_END;". malloc function allocates memory and returns the pointer to the start of that allocated memory block, isn't it? Why do we have to reposition the pointer by subtracting nl+NR_END?


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).



Not open for further replies.

Part and Inventory Search

Welcome to