我正试图在C.中为Java的ArrayList
编写等效的remove
这是我的密码。它假定索引是列表中的有效索引。
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)
会做什么的相互矛盾的事情。
我会离开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
来收缩列表,除非您所在的平台确实内存受限,即使这样,也可能没有必要为每个删除的列表元素收缩分配的块。更喜欢将分配的块增加/缩小一个以上的元素。 -
这确实是一个nit,但由于这是一个API方法,并且您正在使用数据结构的
size
成员来跟踪列表长度,因此您最好始终使用size
,而不是依赖于另一个API方法arrayListSize
。