关于 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中是非包含的)。
假设您有 nl=1
和 NR_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.
C 的任何标准版本都不需要强制转换为 char*
。在古代版本中可能需要。转换 malloc
的 return 值是 also not needed.
《数值食谱》第 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中是非包含的)。
假设您有
nl=1
和NR_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.
C 的任何标准版本都不需要强制转换为
char*
。在古代版本中可能需要。转换malloc
的 return 值是 also not needed.