在数组中使用 memcpy 删除

Deletion Using memcpy in an array

给定一个索引和一个整数数组,我需要通过使用 memcpy() 删除给定数组中存储在给定索引中的元素。新的元素集将存储在给定的数组中。

这是我想做的事情的一个例子,尽管我在实施它时遇到了困难。

因此 arrayElem 删除 10 后将如下所示:

您不能使用 memcpy() 在同一个数组 上执行此操作。您需要使用 memmove().

引用memcpy() man page

The memcpy() function copies n bytes from memory area src to memory area dest. The memory areas must not overlap. Use memmove(3) if the memory areas do overlap.

参考:memmove()

但是,如果您使用临时数组,那么,您可以使用 memcpy() 分两步实现此目的,例如

  • memcpy() 将给定数组的所需部分添加到临时数组
  • memcpy() 将临时数组返回到从所需索引开始的给定数组。

FWIW,上述两种方法都不会 清除 索引 6 中的值。现有值将存在。您需要手动执行此操作。

您不能使用 memcpy, because source and destination overlap, but you can use memmove,例如:

memmove(&a[1], &a[2], 5 * sizeof(a[0]));

这会将从 a[2] 开始的 5 个元素向下复制到从 a[1] 开始的 5 个元素,注意源区域和目标区域重叠这一事实。

您不能使用函数 memcpy,因为数组的范围相互重叠。在这种情况下,行为将是未定义的。

相反,您必须使用标准函数 memmove

这是一个演示程序

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

size_t remove_by_index( int a[], size_t n, size_t i )
{
    if ( i < n )
    {
        memmove( a + i, a + i + 1, ( n - i - 1 ) * sizeof( *a ) );
        --n;
    }

    return n;
}

int main( void ) 
{
    int a[] = { 1, 10, 5, 8, 4, 51, 2 };
    const size_t N = sizeof( a ) / sizeof( *a );
    size_t n = N;

    for ( size_t i = 0; i < n; i++ ) printf( "%d ", a[i] );
    printf( "\n" );

    n = remove_by_index( a, n, 1 );

    for ( size_t i = 0; i < n; i++ ) printf( "%d ", a[i] );
    printf( "\n" );

    return 0;
}

程序输出为

1 10 5 8 4 51 2 
1 5 8 4 51 2 

如果您 "must" 使用 memcpy,那么您可以一次复制 1 个字节,就在数组的下方,以防止源和目标重叠。在这种情况下,memcpy 代表单个内存分配,效率极低,但它会做你想做的。

for(int i=1; i<=5; i++)
{
    memcpy(arrayElem[i], arrayElem[i+1], sizeof(*arrayElem));
}

Icky,但遵守作业中规定的法律条文。 memmove 尽管 100% 是在没有要求的情况下实际执行此操作的正确方法。