I have an array which contains a preallocated memory size for say 1000 elements. There is a counter to track the actual number of elements.
Is it safe to use memcpy to insert an alement at a given position?
If I run this, I see that it works, but I am in doubt about if it works by mere chance or it is fundamentally wrong approach as memcpy can not guarantee that the previous data is going to be preserved.
#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;
}
The output:
---
0002
0004
0006
0008
0010
---
0002
0004
0006
-001
0008
0010
memcpy
has undefined behavior in case the two parameters point to memory that overlaps. You need to use memmove
instead, it exists for this very purpose.
See the friendly manual or the C standard 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.