C从动态数组中删除元素

时间:2012-07-25 18:56:02

标签: c memory-management malloc

我正在尝试在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)会做什么的相互矛盾的事情。

1 个答案:

答案 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