我正在尝试在C中为Java remove
编写等效的ArrayList
。
这是我的代码。它假定索引是列表中的有效索引。
void arrayListRemove(ArrayList* list, int index){
int i;
if (arrayListSize(list)==1){
list->size = 0;
free(list->data);
list->data = NULL;
} else {
for(i=index;i<arrayListSize(list)-1;i++){
list->data[i] = list->data[i+1];
}
list->data = realloc(list->data, (arrayListSize(list) - 1) * sizeof(void*));
if (list->data != NULL){
--list->size;
} else {
exit(1);
}
}
}
这是对的吗?
代码是否可以在没有arrayListSize(list) == 1
检查的情况下运行?即realloc(list->data, 0)
释放arrayList吗?我在网上看到了有关realloc(ptr, 0)
会做什么的相互矛盾的事情。
答案 0 :(得分:3)
我会离开arrayListSize(list) == 1
案件。不依赖于realloc(ptr, 0)
的行为似乎是谨慎的,并且通常使用明确的free
使代码更清晰。
还有一些说明:
使用realloc
时,请务必捕获tmp
变量中的返回值。如果realloc
失败,则它可以返回NULL
并保持原始指针不变。通过执行ptr = realloc(ptr);
,realloc
失败时可能会导致内存泄漏,因为您现在已经丢失了原始指针。而是使用这个成语:
tmp = realloc(ptr, newSize);
if (tmp != NULL)
ptr = tmp;
else handleError();
从列表中删除列表时,是否需要free
列表元素?你的data
数组由指针组成,你是否通过不删除被删除元素上的free
来泄漏内存?当然,这在java实现中不是必需的。如果您的列表包含对包含对象的唯一引用,那么删除后需要free
,或返回函数中的指针并将其留给调用者处理记忆。
通常不需要使用realloc
缩小列表,除非您在真正内存受限的平台上,即使这样,也可能没有必要缩小每个已删除列表元素的已分配块。希望通过多个元素增加/缩小已分配的块。
这真是一个不错的选择,但由于这是一种API方法,并且您使用数据结构的size
成员来跟踪列表长度,因此您可以使用{{1在整个过程中,而不是依赖于另一种API方法size
。