从c数组中删除元素

从c数组中删除元素,c,arrays,C,Arrays,我需要从数组中删除一个特定的元素,该数组将动态调整大小,以便使用realloc存储未知数量的元素 为了控制分配的内存和定义的元素,我还有两个其他变量: double *arr = NULL; int elements = 0; int allocated = 0; 在数组中放置一些元素之后,我可能需要删除其中的一些元素。我发现的所有文本都说要使用memmove,并通过删除元素的数量减少变量 我怀疑这种方法是否安全有效。我认为这是您可以使用的关于安全的最有效的函数(memcpy不是选项)-您需要

我需要从数组中删除一个特定的元素,该数组将动态调整大小,以便使用
realloc
存储未知数量的元素

为了控制分配的内存和定义的元素,我还有两个其他变量:

double *arr = NULL;
int elements = 0;
int allocated = 0;
在数组中放置一些元素之后,我可能需要删除其中的一些元素。我发现的所有文本都说要使用
memmove
,并通过删除元素的数量减少变量


我怀疑这种方法是否安全有效。

我认为这是您可以使用的关于安全的最有效的函数(
memcpy
不是选项)-您需要确保参数正常,否则会发生不好的事情:)

我认为这是您可以使用的最有效的函数(
memcpy
不是一个选项)关于安全性-您需要确保参数是正确的,否则会发生不好的事情:)

使用memmove肯定是有效的,并且安全性不会明显低于在数组上迭代。要了解实现的实际安全性,我们需要查看代码,特别是memmove调用,以及如何检查realloc的返回结果


如果您的memmove错误,或者没有检查任何realloc返回,则可能会发生崩溃

使用memmove肯定是有效的,而且安全性不会明显低于在数组上迭代。要了解实现的实际安全性,我们需要查看代码,特别是memmove调用,以及如何检查realloc的返回结果


如果您的memmove错误,或者没有检查任何realloc返回,则可能会发生崩溃

原则上,假设您正确计算了地址和长度,您可以使用memmove,但请注意,如果您用索引更高的元素覆盖一个或多个元素,并且这些被覆盖的元素是包含指向已分配内存的指针的结构,则可能会产生泄漏


注意,在使用memmove之前,必须首先妥善处理要覆盖的元素。如何处理它们取决于它们代表什么。如果它们只是包含指向其他结构的指针的结构,但不“拥有”分配的内存,则不会发生任何事情。如果指针“拥有”内存,则必须首先释放内存

原则上,假设您正确计算了地址和长度,您可以使用memmove,但请注意,如果您用索引更高的元素覆盖一个或多个元素,并且这些被覆盖的元素是包含指向已分配内存的指针的结构,则可能会产生泄漏


注意,在使用memmove之前,必须首先妥善处理要覆盖的元素。如何处理它们取决于它们代表什么。如果它们只是包含指向其他结构的指针的结构,但不“拥有”分配的内存,则不会发生任何事情。如果指针“拥有”内存,则必须首先释放内存

数据分区可以提高
memmove()
realloc()
的性能。通过数据分区,我的意思是使用多个数组块,而不是一个大数组

除了
memmove()
,我发现内存交换是一种有效的方法。但也有缺点。可以通过这种方式更改数组顺序

int remove_element(int*from, int total, int index) {
        if(index != (total-1))
                from[index] = from[total-1];
        return total-1; // return the number of elements
}
有趣的是,这个数组可以被索引随机访问。随机删除一个元素也可能会影响其他元素的索引。如果此移除是在数组的循环遍历中完成的,则重新排序可能会导致意外结果

解决此问题的一种方法是使用
为空白的
掩码数组并延迟删除

int remove_element(int*from, int total, int*is_valid, int index) {
        is_blank[index] = 1;
        return total; // **DO NOT DECREASE** the total here
}
它可以创建一个稀疏数组。但是也可以在空白位置添加新元素。 同样,可以使用以下高效的交换算法使阵列紧凑

int sparse_to_compact(int*arr, int total, int*is_valid) {
        int i = 0;
        int last = total - 1;
        // trim the last blank elements
        for(; last >= 0 && is_blank[last]; last--); // trim blank elements from last

        // now we keep swapping the blank with last valid element
        for(i=0; i < last; i++) {
                if(!is_blank[i])
                        continue;
                arr[i] = arr[last]; // swap blank with the last valid
                last--;
                for(; last >= 0 && is_blank[last]; last--); // trim blank elements
        }
        return last+1; // return the compact length of the array
}
int稀疏到紧凑(int*arr,int-total,int*有效){
int i=0;
int last=总计-1;
//修剪最后的空白元素
for(;last>=0&&is_blank[last];last--);//从last中修剪空白元素
现在我们继续用最后一个有效元素交换空白。
对于(i=0;i=0&&is_blank[last];last--);//修剪空白元素
}
return last+1;//返回数组的压缩长度
}

请注意,上面的算法使用swap并更改元素顺序。在阵列上的某些循环操作之外使用可能是首选/安全的。如果元素的索引保存在某个地方,那么它们也需要更新/重建。

数据分区可以提高
memmove()
realloc()
的性能。通过数据分区,我的意思是使用多个数组块,而不是一个大数组

除了
memmove()
,我发现内存交换是一种有效的方法。但也有缺点。可以通过这种方式更改数组顺序

int remove_element(int*from, int total, int index) {
        if(index != (total-1))
                from[index] = from[total-1];
        return total-1; // return the number of elements
}
有趣的是,这个数组可以被索引随机访问。随机删除一个元素也可能会影响其他元素的索引。如果此移除是在数组的循环遍历中完成的,则重新排序可能会导致意外结果

解决此问题的一种方法是使用
为空白的
掩码数组并延迟删除

int remove_element(int*from, int total, int*is_valid, int index) {
        is_blank[index] = 1;
        return total; // **DO NOT DECREASE** the total here
}
它可以创建一个稀疏数组。但是也可以在空白位置添加新元素。 同样,可以使用以下高效的交换算法使阵列紧凑

int sparse_to_compact(int*arr, int total, int*is_valid) {
        int i = 0;
        int last = total - 1;
        // trim the last blank elements
        for(; last >= 0 && is_blank[last]; last--); // trim blank elements from last

        // now we keep swapping the blank with last valid element
        for(i=0; i < last; i++) {
                if(!is_blank[i])
                        continue;
                arr[i] = arr[last]; // swap blank with the last valid
                last--;
                for(; last >= 0 && is_blank[last]; last--); // trim blank elements
        }
        return last+1; // return the compact length of the array
}
int稀疏到紧凑(int*arr,int总计,