我正在尝试用 C 语言为 Java 的 ArrayList
编写相当于 remove
的内容。
这是我的代码。它假设index是列表中的有效索引。
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
检查,代码还能工作吗? IE。 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();
从列表中删除列表中的元素时是否有必要
释放
这些元素?您的data
数组由指针组成,您是否因不在删除的元素上调用free
而泄漏内存?当然,这在 java 实现中不是必需的。如果您的列表包含对所包含对象的唯一引用,那么您需要在删除时释放
它们,或返回函数中的指针并将其留给调用者处理内存。通常不需要使用
realloc
来缩小列表,除非您所在的平台确实内存受限,即使如此,它也是如此可能没有必要缩小每个已删除列表元素的分配 block 。更喜欢将分配的 block 增大/缩小多个元素。这确实是一个问题,但由于这是一个 API 方法,并且您正在使用数据结构的
size
成员来跟踪列表长度,因此您不妨使用size
自始至终,而不是依赖于另一个 API 方法arrayListSize
。
关于C 从动态数组中删除元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11656648/