如何在malloc上的数组中插入元素?

时间:2009-11-22 04:49:38

标签: c

说我们要在malloc上的数组中插入一个元素。我知道在哪里以及如何插入,但是我很难将每个后续元素向下移动1.对此技术方法是什么?感谢

| x x x x x x x x x x x | original array
| x x x x x 0 x x x x x x | new array

假设我们无法使用“memmove”功能......

3 个答案:

答案 0 :(得分:4)

是的,如果您需要在没有memmove的情况下执行此操作,则可以使用简单的循环执行此操作。请注意,您可能还需要先使用realloc,以扩展已分配数组的大小,以使其适合新元素。

这个技巧就是让循环将每个元素向前移动一步,从最后一个元素开始。片刻的反思应该告诉你为什么这是必要的。

答案 1 :(得分:3)

无论数组是动态分配,静态分配还是自动分配,基本原理都是相同的。主要区别在于,如果动态分配的数组中没有足够的空间,您可以使用更多空间重新分配它(受制于一些系统强加的限制。假设数组中有足够的空间,您可以使用memmove()来在目标位置向上一个空格后复制数组的部分,然后将目标位置设置为插入的值。或者你可以写一个循环来完成这项工作。

int *dynarr = malloc(24 * sizeof(*dynarr));
int  idx = 0;
dynarr[idx++] = 0;
dynarr[idx++] = 23;
dynarr[idx++] = 34;
dynarr[idx++] = 9;
dynarr[idx++] = 15;

现在插入位置n = 2:

memmove(&dynarr[n+1], &dynarr[n], (idx - n) * sizeof(int));
dynarr[n] = 19;
idx++;

这是一个批量移动,一个赋值,并递增计数器,因为数组中还有一个元素。


由于问题被编辑为禁止memmove(),这里是一个简单数组索引的解决方案,假设使用相同的初始化序列:

int i;
int n = 2;

for (i = idx; i > n; i--)
{
    dynarr[i] = dynarr[i-1];
}
dynarr[n] = 19;
idx++;

完整的示例代码:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

static void print_array(int *a, int n)
{
    int i;
    for (i = 0; i < n; i++)
    {
        printf("a[%d] = %d\n", i, a[i]);
    }
}

int main()
{
    {
        int *dynarr = malloc(24 * sizeof(*dynarr));
        int  idx = 0;
        dynarr[idx++] = 0;
        dynarr[idx++] = 23;
        dynarr[idx++] = 34;
        dynarr[idx++] = 9;
        dynarr[idx++] = 15;

        printf("Before insert\n");
        print_array(dynarr, idx);
        int n = 2;
        memmove(&dynarr[n+1], &dynarr[n], (idx - n) * sizeof(int));
        dynarr[n] = 19;
        idx++;
        printf("After insert\n");
        print_array(dynarr, idx);
        free(dynarr);
    }

    {
        int *dynarr = malloc(24 * sizeof(*dynarr));
        int  idx = 0;
        dynarr[idx++] = 0;
        dynarr[idx++] = 23;
        dynarr[idx++] = 34;
        dynarr[idx++] = 9;
        dynarr[idx++] = 15;

        printf("Before insert\n");
        print_array(dynarr, idx);

        int n = 2;
        int i;

        for (i = idx; i > n; i--)
        {
            dynarr[i] = dynarr[i-1];
        }
        dynarr[n] = 19;
        idx++;
        printf("After insert\n");
        print_array(dynarr, idx);
        free(dynarr);
    }

    return(0);
}

答案 2 :(得分:1)

正如Don建议的那样,memmove()将允许移动此数组的一部分,以便为新元素腾出空间。

根据数组中元素的大小,您还可以考虑在数组中仅存储指针,以便在访问单个元素时以额外的间接为代价,更容易/更快地重新排列数组。 (并且还需要管理单个元素大小的内存块)。决定这种方法取决于数组元素的重组量以及它们的大小。

警告:鉴于问题中添加的“图片”,如果内存移动意味着写入超过最初分配的内存大小,则memmove()或任何操作可能是不可能的!
如果这确实是我们想要的,那么指针数组的概念可能更合适,因为这允许最初分配一个超大的内存块(适用于数组)并根据需要分配(或处理)单个元素。 / p>

编辑:“我们不允许使用memmove()”表示某种形式的作业。 (顺便说一句就这样标记!!!)
为了更好地帮助您,我们需要了解问题的特定前提。这似乎是看起来像是:

1) we readily have an array, containing say N elements.
2) the array on the heap, i.e. it was allocated using malloc() (or related
   functions)
3) the effective size of the malloc-ated block of memory is bigger than that of
   the array.  
  Is #3  true ?
4) Depending on #3 we need to either allocate a new memory block (a bigger one)
   and copy the array.  We expect this copy would be done in 3 steps
       - copy the elements that precede the new element
       - copy the new element
       - copy the elements that are after the new element
   or...  (if we have enough room), we'd require two steps
       - "shift" the elements that are supposed to be after the new element
         This can be done one element at a time, if we wish to avoid memcopy
       - copy the new element.