关于 Numerical recipes,第 2 版的问题:allocation/deallocation 向量内存

Question on book Numerical recipes, 2nd ed.: allocation/deallocation of memory for vectors

《数值食谱》第 2 版 (http://numerical.recipes) 使用以下代码来 allocate/deallocate 一个带有下标 [nl..nh] 的向量 v 的内存:

#define NR_END 1
#define FREE_ARG char*

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;
}

void free_vector(float *v, long nl, long nh)
/* free a float vector allocated with vector() */
{
  free((FREE_ARG) (v+nl-NR_END));
}

问题 1:adding/subtracting NR_END 元素的用途是什么?

问题2:在free_vector中将float *转换为char *的目的是什么?

我理解malloc中的+1是由于数组的右边界包含(通常在C中是非包含的)。

  1. 假设您有 nl=1NR_END=0。然后 returned 指针将越界(它指向分配的块之前)。这是未定义的行为,可能导致不正确的结果,尽管它不太可能在主要编译器上引起问题,因为指针会在取消引用之前递增。

    为避免这种未定义的行为,您可以将NR_END设置为nl的最大期望值(书中为1)。这保证了 returned 指针是有效的。但是,问题中给出的实现仍然不正确,因为 v-nl+NR_END 在递增 NR_END 之前递减 nl。正确的实现是 v+NR_END-nl.

    请注意,如果 nl 仅具有非负值,则更简单的实现是简单地分配 nh+1 值,然后在 [= 之后不需要任何指针运算20=] 或 free.

    之前

    Here 您可以在第二版的第 940-941 页中看到书中的一段话对此进行了解释。一些引用:

    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.

    [....]

    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.

  2. C 的任何标准版本都不需要强制转换为 char*。在古代版本中可能需要。转换 malloc 的 return 值是 also not needed.