2

我正在尝试用 C 编写相当于removefor Java 的ArrayList东西。

这是我的代码。它假定 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如果没有检查,代码会工作吗?即realloc(list->data, 0)释放arrayList?我在网上看到了关于该怎么realloc(ptr, 0)做的相互矛盾的事情。

4

1 回答 1

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用于缩小列表,除非您在一个真正内存受限的平台上,即使那样,也可能没有必要为每个已删除的列表元素缩小分配的块。更喜欢将分配的块扩大/缩小一个以上的元素。

  • 这确实是一个 nit,但由于这是一个 API 方法,并且您正在使用size数据结构的成员来跟踪列表长度,因此您最好size始终使用它,而不是依赖另一个 API 方法arrayListSize

于 2012-07-25T18:59:47.800 回答