我有两个用于删除数组
的示例函数第一个使用memmove,这种方法在释放为输入数组分配的内存时会产生问题(输入数组总是malloc'd,例如它在堆上)?
在调用此函数之前,双精度输入数组已被malloc。该函数试图删除数组中的值,例如使标准数组看起来有点像动态数组。但是,memmove调用是否意味着当输入数组随后被释放时(在此函数返回后该函数之外),由于数组已被修改,对free的调用可能无法正常工作?
/**
* Remove a contiguous section of data from an array of doubles
*/
void dbl_array_del(double *array, size_t *plen_array, size_t idx, size_t n_elems)
{
size_t len_array = *plen_array;
/* must delete at least one value */
assert(n_elems > 0);
/* section to remove does not exceed the length of the array */
assert(idx+n_elems <= len_array);
/* function cannot create an 'empty' array */
assert(len_array-n_elems > 0);
if ( (idx+n_elems) == len_array) {
/* case where section to be removed reaches end of array, no memory has
* to be shifted, only array length altered */
len_array-=n_elems;
} else {
/* otherwise data to right of section has to be shifted left, back over
* removed section */
memmove(array+idx, array+idx+n_elems,
(len_array-idx-n_elems)*sizeof(double));
len_array-=n_elems;
}
*plen_array = len_array;
}
第二种方法不使用memmove,而是迭代需要向左移动的值。就内存泄漏而言,这是一种更安全的方法吗?
/**
* Remove a contiguous section of data from an array of doubles
*/
void dbl_array_del(double *array, size_t *plen_array, size_t idx, size_t n_elems)
{
size_t len_array = *plen_array;
/* must delete at least one value */
assert(n_elems > 0);
/* section to remove does not exceed the length of the array */
assert(idx+n_elems <= len_array);
/* function cannot create an 'empty' array */
assert(len_array-n_elems > 0);
/* n is the no. of values that need shifting left */
size_t n = len_array-(idx+n_elems);
size_t i;
/* shift values left */
for (i=idx; i<idx+n; i++) {
array[i] = array[i+n_elems];
}
/* reset values off end of array */
for (i=idx+n; i<len_array; i++) {
array[i] = 0;
}
*plen_array = len_array-n_elems;
}
答案 0 :(得分:2)
Memmove不会伤害你对free()的呼唤。它基本上只是隐藏在函数中的for-Loop(可能具有一些特定于机器的优化)。
如果使用malloc()分配了一个块,则系统会记住在返回的指针上调用free()时要取消分配的项数。当您使用memmove()或您自己编写的for循环更改数组内容时,这不会改变。
答案 1 :(得分:0)
就安全性而言,最好的办法是不要使用这样的原始C阵列。 std :: vector提供了一种安全管理(调整大小/删除/重定位/等...)基础数据的机制。
也就是说,在上面的示例中,任何一种解决方案都允许您覆盖内存。在安全方面,没有更好的方法。在性能方面,memmove解决方案可以有一个定制的实现,可以比手动一次移动元素更快。