rob@kaa.eng.ohio-state.edu (Rob Carriere) (08/31/88)
In article <1673@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter Bright) writes: >In article <531@accelerator.eng.ohio-state.edu> rob@kaa.eng.ohio-state.edu >(Rob Carriere) writes: ><In article <13258@mimsy.UUCP< chris@mimsy.UUCP (Chris Torek) writes: ><< [ still on the b = malloc( foo ); bb = b - 1; code in NumRecipes ] >< [ claiming astonishment in accordance with the Least of.. Principle ] >On a segmented architecture, like 8086's, malloc can and does return >a value that is a pointer to the beginning of a segment. Yes, and as I've written people who e-mailed me this argument, that spells out ``broken compiler'' if it gives problems ('cause you can't malloc more than 64K that way). Of course on a machine with large segments, the counterargument doesn't quite hold water either, so... >[ unItelligent CPU explanation deleted ] > array = malloc(MAX * sizeof(array[0])); > for (p = &array[MAX-1]; p >= &array[0]; p--) No! That wasn't the problem! (Wish it was, that'd be easy to avoid!). The problem is that the authors of Numerical Recipes (NR) observe, correctly, that many numerical problems are naturally non-zero based. This gives you the choice between carrying around boatloads of index arithmatic (inefficient and error-prone), or making non-zero based arrays. They opt for the latter, in the following way: float *my_vec; /* this is going to be a vector */ int nl, nh; ... my_vec = vector( nl, nh ); /* allocates a vector with lowest valid index nl, and highest valid index nh */ ... my_vec[3] = foo(bar); ... Where we have: float *vector( nl, nh ) int nl; int nh; { float *v; v = (float *)malloc( ( nh-nl +1 )* sizeof(float) ); if( v == 0 ) nrerror( "Allocation error in vector()" ); return v - nl; } This is quite a bit more disciplined than the example above; it is also quite bit more fundamental. Fortunately, as far as I've checked at least, NR only uses vectors and matrices with either 0 or unit offset, so on broken architectures you could always do malloc( (nh + 1 )* sizeof(float) ); return v; This would waste a float per vector, and a pointer-to-float plus n floats for an n-by-something matrix. Ugly, but it works. (and we *are* the throw-away culture after all :-) Rob Carriere