3

嘿嘿。在我的 C 程序中,我处理大量的操作,在这些操作中我必须读取文件并将其数据存储在数组中。为此,由于 C 中的数组处理有点复杂,我正在使用这篇文章中建议的以下代码:C 动态增长数组

typedef struct {
    float *array;
    size_t used;
    size_t size;
} points;

void initArrayInd(arrayInd *a, size_t initialSize) {
    a->array = (GLubyte *)malloc(initialSize * sizeof(GLubyte));
    a->used = 0;
    a->size = initialSize;
}

void insertArrayInd(arrayInd *a, GLubyte element) {
    if (a->used == a->size) {
        a->size *= 2;
        a->array = (GLubyte *)realloc(a->array, a->size * sizeof(GLubyte));
    }
    a->array[a->used++] = element;
}

void freeArrayInd(arrayInd *a) {
    free(a->array);
    a->array = NULL;
    a->used = a->size = 0;
}

我已经习惯了 Java 编程,所以在大多数情况下,我认为应该如何编写代码的方式是错误的。我想,基于这个动态数组分配,能够创建一个新函数,它将在我指定的位置插入一条记录。我想知道这样做的最佳方法是什么。

我是否应该在数组末尾插入新记录,然后将所有内容移一个位置。我应该创建一个新数组,复制 i-1 个元素,然后放置 i 并复制 i+n 个元素。我是否应该将初始数组一分为二,创建第三个并将所有内容混合在一起。C 中实现这一目标的最佳方法是什么?

编辑:这会做吗?

void insertFPointsAt(points *a, float element, int position) {
    if (a->used == a->size) {
        a->size *= 2;
        a->array = (float *)realloc(a->array, a->size * sizeof(float));
    }
    memmove(&a->array[position], &a->array[position+1], &a->array[a->used] - &a->array[position]);
    a->array[position] = element;
}
4

2 回答 2

4

在数组中间插入时,需要实现这个算法:

  • 检查是否有足够的空间容纳要插入的元素
  • 如果您没有足够的空间,请按照在末尾添加元素时的方式扩展数组
  • 使用将数据向上移动一个位置memmove
  • 将元素放置在调用者请求的位置

唯一不同于在末尾插入的步骤是第三个步骤,您将数组的内容向上移动一个元素。memmove即使两个区域重叠,函数也能正确处理这个问题。

编辑:呼叫memmove应如下所示:

memmove(&a->array[position+1], &a->array[position], &a->array[a->used] - &a->array[position]);

一些附加说明:

  • 释放数组后将数组增加到两倍大小将不起作用,因为您将大小设置为零。
  • 与需要转换的 C++ 不同malloc,C 不要求您转换malloc/ calloc/的返回值realloc
于 2013-04-28T20:35:13.283 回答
1

您只需要在尝试插入的索引之后移动元素。当您调整数组大小时,您会遇到不必要的复制 -realloc调用可能会为您复制,而您最终会复制两次。我会做类似的事情:

insert element E at index I:
   if resize is necessary:
       - allocate new larger buffer
       - copy elements 0 to I-1 from old buffer into new buffer
       - insert E at index I of new buffer
       - copy elements I to end of old buffer into new buffer, starting at index I+1
       - free old buffer
   else
       - copy elements I to end of buffer 'up by one' index
       - insert E at index I of the buffer
于 2013-04-28T20:33:38.117 回答