从数组中删除节

时间:2014-01-29 09:47:47

标签: c arrays

我有两个用于删除数组

的示例函数

第一个使用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;
}  

2 个答案:

答案 0 :(得分:2)

Memmove不会伤害你对free()的呼唤。它基本上只是隐藏在函数中的for-Loop(可能具有一些特定于机器的优化)。

如果使用malloc()分配了一个块,则系统会记住在返回的指针上调用free()时要取消分配的项数。当您使用memmove()或您自己编写的for循环更改数组内容时,这不会改变。

答案 1 :(得分:0)

就安全性而言,最好的办法是不要使用这样的原始C阵列。 std :: vector提供了一种安全管理(调整大小/删除/重定位/等...)基础数据的机制。

也就是说,在上面的示例中,任何一种解决方案都允许您覆盖内存。在安全方面,没有更好的方法。在性能方面,memmove解决方案可以有一个定制的实现,可以比手动一次移动元素更快。