《数字食谱》第二版(http://numerical.recipes)使用以下代码为下标为[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:添加/减去NR_END元素的目的是什么?问题2:在float *中将char *转换为free_vector的目的是什么?我知道+1中的malloc是由于数组的包含右边界(通常在C中是非包含的)。 最佳答案 假设你有nl=1和NR_END=0。然后返回的指针将超出边界(它指向分配的块之前)。这是未定义的行为,可能会导致不正确的结果,尽管它不太可能在主要编译器上造成问题,因为指针在被取消引用之前会被递增。为了避免这种未定义的行为,您可以将 >设置为最大期望值的 >(这是书中的1)。这保证了返回的指针是有效的。但是,问题中给出的实现仍然不正确,因为NR_END在递增nl之前递减v-nl+NR_END。正确的实现方法是nl。注意,如果NR_END只有非负值,一个简单得多的实现是简单地分配v+NR_END-nl值,然后您不需要在nl之后或nh+1之前使用任何指针算法。Here您可以从第二版第940-941页的书中看到一段解释这一点的引文。一些引用:它可能在极少数情况下(可能仅在分段机器上),表达式b-1完全没有代表。如果发生这种情况,则不能保证b=(b-1)+1表示满意。[....]参数NRúEND用作一些额外的存储器在每个向量或矩阵块的开头分配的位置,仅用于使偏移指针引用保证可表示。在任何标准化的C版本中,都不需要使用到malloc的强制转换。它可能在古代版本中是必需的。投射free的返回值为also not needed。关于c - 书中的问题《数字配方》,第二版: vector 的内存分配/取消分配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53378855/
10-11 21:45