说我们要在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”功能......
答案 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.