C从动态数组中移除元素



我正试图在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

相关内容

  • 没有找到相关文章

最新更新