C 从动态数组中删除元素

标签 c memory-management malloc

我正在尝试用 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/

相关文章:

ios - 我需要澄清一下我是否应该(可以?)解除分配与 View 相关的 UI 元素

c - C语言中的欧拉恒等式

java - 如何计算Java程序的内存使用量?

c - 强制某些编译器生成的变量进入特定的 ELF 部分(使用 gcc)

objective-c - 使用弱指针的 N​​SMutableArray

c++ - calloc 覆盖另一个变量的内存?

用指针调用函数不会改变该指针的值?

c - 指针 - 转换为结构指针 + Malloc

c - 空终止的 C 字符数组

c - void*,字符串和字符的指针