C 从数组中删除节
我有两个示例函数用于删除数组的一部分 第一种方法使用memmove,在释放分配给输入数组的内存时(输入数组总是malloc'd,例如它在堆上),这种方法会导致问题吗 在调用此函数之前,double的输入数组已被malloc'd。此函数尝试删除数组中的值,例如,使标准数组看起来有点像动态数组。但是,memmove调用是否意味着当输入数组随后被释放时(在该函数返回后,在该函数之外),由于数组已被修改,对free的调用可能无法正常工作C 从数组中删除节,c,arrays,C,Arrays,我有两个示例函数用于删除数组的一部分 第一种方法使用memmove,在释放分配给输入数组的内存时(输入数组总是malloc'd,例如它在堆上),这种方法会导致问题吗 在调用此函数之前,double的输入数组已被malloc'd。此函数尝试删除数组中的值,例如,使标准数组看起来有点像动态数组。但是,memmove调用是否意味着当输入数组随后被释放时(在该函数返回后,在该函数之外),由于数组已被修改,对free的调用可能无法正常工作 /** * Remove a contiguous sectio
/**
* 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;
}
/**
*从双精度数组中删除连续的数据段
*/
void dbl\u array\u del(双*数组、大小*plen\u数组、大小*idx、大小元素)
{
大小\u t len\u数组=*plen\u数组;
/*必须删除至少一个值*/
断言(n_元素>0);
/*要删除的节不超过数组的长度*/
断言(idx+n_元素0);
if((idx+n元素)=len_数组){
/*如果要删除的节到达数组的末尾,则没有内存
*要进行移位,只需更改数组长度*/
len_数组-=n_元素;
}否则{
/*否则,段右侧的数据必须向左、向后移动
*删除的部分*/
memmove(数组+idx,数组+idx+n_元素,
(len_阵列-idx-n_元素)*sizeof(双元素);
len_数组-=n_元素;
}
*plen_阵列=len_阵列;
}
第二种方法不使用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;
}
/**
*从双精度数组中删除连续的数据段
*/
void dbl\u array\u del(双*数组、大小*plen\u数组、大小*idx、大小元素)
{
大小\u t len\u数组=*plen\u数组;
/*必须删除至少一个值*/
断言(n_元素>0);
/*要删除的节不超过数组的长度*/
断言(idx+n_元素0);
/*n是需要向左移动的值的数量*/
大小n=长度数组-(idx+n个元素);
尺寸i;
/*向左移动值*/
对于(i=idx;i而言,从安全角度来看,最好不要使用像这样的原始C数组。std::vector提供了一种安全管理(调整大小/删除/重新定位等)底层数据的机制
也就是说,在您上面的示例中,任何一种解决方案都将允许您覆盖内存。就安全性而言,没有更好的方法。就性能而言,memmove解决方案可以有一个定制的实现,其速度可能比手动一次移动一个元素更快。memmove不会影响您对free()的调用它基本上只是隐藏在函数中的for循环(可能是一些特定于机器的优化)
如果已使用malloc()分配了块,则当您对返回指针调用free()时,系统会记住要取消分配多少项。当您使用memmove()更改数组内容时,这一点不会改变或者您自己编写的for循环。我不确定内存泄漏是否是您的主要问题。由于两个版本都没有单独分配内存,内存泄漏根本就不会出现。您认为可能会出现什么样的问题还不清楚。是的,我只是担心-在这种情况下,切换到“适当”的动态数组会可能是杀伤力太大了-需要一个黑客只是为了让它看起来有些值已经被删除了Hanks-这正是我想要的确认,memmove不会影响自由..我的大脑在内存管理问题上会时不时地抽搐如果你想回收内存,你必须重新定位(3)数组。但那是另一个麻烦…@vonbrand你是什么意思?在调用adbl_array_del()后释放输入数组将足以释放所有分配的堆内存-底层的c数组始终是相同的长度-它只是将其内容四处移动以使其“看起来”更小。无需realloc。。