使用 memcpy 在分配大小更大的数组中插入元素是否安全?
Is it safe to use memcpy to insert an element in an array which has greater allocated size?
我有一个数组,其中包含为 1000 个元素预分配的内存大小。
有一个计数器来跟踪元素的实际数量。
使用 memcpy 在给定位置插入元素是否安全?
如果我 运行 这个,我看到它有效,但我怀疑它是否有效,或者它是根本错误的方法,因为 memcpy 不能保证以前的数据会被保留。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int *list;
int list_size;
// PREALLOCATE SPACE FOR 1000 ITEMS
list = calloc(sizeof(int), 1000);
list_size = 0;
// ADD ITEMS
list[0] = 2; list_size++;
list[1] = 4; list_size++;
list[2] = 6; list_size++;
list[3] = 8; list_size++;
list[4] = 10; list_size++;
// LIST ITEMS
printf("---\n"); for(int i=0; i<list_size; i++) printf("%04d\n", list[i]);
// WE WANT TO INSERT A NUMBER AT A GIVEN POSITION (IN THIS CASE WE HAVE A POINTER TO THE ITEM)
int *p = &list[3];
// WE WANT TO PUSH FORWARD ALL THE ELEMENTS OF THE ARRAY BEFORE INSERTING THE ELEMENT
memcpy( p+1, p, (list_size - (p - list))*sizeof(int));
list_size++;
// INSERT ELEMENT
*p = -1;
// LIST ITEMS
printf("---\n"); for(int i=0; i<list_size; i++) printf("%04d\n", list[i]);
return 0;
}
输出:
---
0002
0004
0006
0008
0010
---
0002
0004
0006
-001
0008
0010
如果两个参数指向重叠的内存,memcpy
具有未定义的行为。您需要改用 memmove
,它的存在就是为了这个目的。
查看友好手册或C标准7.24.1:
The memcpy
function copies n characters from the object pointed to by s2 into the
object pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined.
The memmove
function copies n characters from the object pointed to by s2 into the
object pointed to by s1. Copying takes place as if the n characters from the object
pointed to by s2 are first copied into a temporary array of n characters that does not
overlap the objects pointed to by s1 and s2, and then the n characters from the
temporary array are copied into the object pointed to by s1.
我有一个数组,其中包含为 1000 个元素预分配的内存大小。 有一个计数器来跟踪元素的实际数量。
使用 memcpy 在给定位置插入元素是否安全?
如果我 运行 这个,我看到它有效,但我怀疑它是否有效,或者它是根本错误的方法,因为 memcpy 不能保证以前的数据会被保留。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int *list;
int list_size;
// PREALLOCATE SPACE FOR 1000 ITEMS
list = calloc(sizeof(int), 1000);
list_size = 0;
// ADD ITEMS
list[0] = 2; list_size++;
list[1] = 4; list_size++;
list[2] = 6; list_size++;
list[3] = 8; list_size++;
list[4] = 10; list_size++;
// LIST ITEMS
printf("---\n"); for(int i=0; i<list_size; i++) printf("%04d\n", list[i]);
// WE WANT TO INSERT A NUMBER AT A GIVEN POSITION (IN THIS CASE WE HAVE A POINTER TO THE ITEM)
int *p = &list[3];
// WE WANT TO PUSH FORWARD ALL THE ELEMENTS OF THE ARRAY BEFORE INSERTING THE ELEMENT
memcpy( p+1, p, (list_size - (p - list))*sizeof(int));
list_size++;
// INSERT ELEMENT
*p = -1;
// LIST ITEMS
printf("---\n"); for(int i=0; i<list_size; i++) printf("%04d\n", list[i]);
return 0;
}
输出:
---
0002
0004
0006
0008
0010
---
0002
0004
0006
-001
0008
0010
memcpy
具有未定义的行为。您需要改用 memmove
,它的存在就是为了这个目的。
查看友好手册或C标准7.24.1:
The
memcpy
function copies n characters from the object pointed to by s2 into the object pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined.
The
memmove
function copies n characters from the object pointed to by s2 into the object pointed to by s1. Copying takes place as if the n characters from the object pointed to by s2 are first copied into a temporary array of n characters that does not overlap the objects pointed to by s1 and s2, and then the n characters from the temporary array are copied into the object pointed to by s1.