在数组中使用 memcpy 删除
Deletion Using memcpy in an array
给定一个索引和一个整数数组,我需要通过使用 memcpy()
删除给定数组中存储在给定索引中的元素。新的元素集将存储在给定的数组中。
这是我想做的事情的一个例子,尽管我在实施它时遇到了困难。
因此 arrayElem
删除 10 后将如下所示:
您不能使用 memcpy()
在同一个数组 上执行此操作。您需要使用 memmove()
.
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% 是在没有要求的情况下实际执行此操作的正确方法。
给定一个索引和一个整数数组,我需要通过使用 memcpy()
删除给定数组中存储在给定索引中的元素。新的元素集将存储在给定的数组中。
这是我想做的事情的一个例子,尽管我在实施它时遇到了困难。
因此 arrayElem
删除 10 后将如下所示:
您不能使用 memcpy()
在同一个数组 上执行此操作。您需要使用 memmove()
.
The
memcpy()
function copies n bytes from memory areasrc
to memory areadest
. The memory areas must not overlap. Usememmove(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% 是在没有要求的情况下实际执行此操作的正确方法。