我需要从数组中删除特定元素,动态调整该数组的大小,以便使用realloc
存储未知数量的元素。
为了控制分配的内存和已定义的元素,我还有另外两个变量:
double *arr = NULL;
int elements = 0;
int allocated = 0;
将一些元素放入数组后,我可能需要删除其中的一些元素。我发现的所有文本都说使用memmove
并根据删除的元素数减少变量。
我怀疑这种方法是否安全有效。
答案 0 :(得分:4)
我认为这是你可以使用的最有效的功能(memcpy
不是一个选项)关于安全 - 你需要确保参数是正确的,否则会发生不好的事情:)
答案 1 :(得分:2)
使用 memmove 肯定是高效的,并且不会比迭代数组的安全性低得多。要知道实现的实际安全性,我们需要查看代码,特别是 memmove 调用以及如何检查realloc的返回结果。
如果您的 memmove 错误,或者未检查任何 realloc ,则会发生崩溃。
答案 2 :(得分:1)
原则上,假设您正确计算地址和长度,可以使用memmove,但请注意,如果使用较高索引处的元素覆盖一个或多个元素,并且这些覆盖的元素是包含指向已分配内存的指针的结构,你可能会产生泄漏。
IOW,在使用memmove之前,您必须首先妥善处理您要覆盖的元素。你如何处置它们取决于它们代表什么。如果它们只是包含指向其他结构的指针的结构,但它们不“拥有”分配的内存,则没有任何反应。如果指针“拥有”内存,则必须首先取消分配。
答案 3 :(得分:0)
数据分区可以提高<form id="new_post" name="new_post" method="post" action="" class="" enctype="multipart/form-data">
<input type="text" id="s_name" name="s_name"/>
<input type="file" name="s_image" id="s_image" tabindex="25" />
<input type="submit" value="Create post and upload image" id="submit" name="submit"/>
<input type="hidden" id="new_cpt_action" name="new_cpt_action" value="new_cpt" />
</form>
和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
}
掩码数组并推迟删除。
is_blank
它可能会创建一个稀疏数组。但是,当空白位置添加新元素时,也可以填充它。
同样,可以在以下有效交换算法中使阵列紧凑。
int remove_element(int*from, int total, int*is_valid, int index) {
is_blank[index] = 1;
return total; // **DO NOT DECREASE** the total here
}
请注意,上面的算法使用swap,它会更改元素顺序。可能是在阵列上的某些循环操作之外使用它是首选/安全的。如果元素的索引保存在某个地方,它们也需要更新/重建。