I found something strange about the memcpy() and memset() functions in MSVC2017 and I cannot explain it. Specifically, the 'destination' gets indexed not by single bytes but by the whole size of a structure ('size' argument).
So I have a struct:
typedef struct _S
{
int x;
int y;
} S;
And the code goes like follows:
S* array = (S*)malloc(sizeof(S) * 10); /* Ok. Allocates enough space for 10 structures. */
S s; /* some new structure instance */
/* !!! here is the problem.
* sizeof(S) will return 8
* 8*1 = 8
* now the starting address will be: array+8
* so I'm expecting my structure 's' to be copied to
* the second ''element'' of 'array' (index 1)
* BUT in reality it will be copied to the 7th index!
*/
memcpy(array + (sizeof(S) * 1), &s, sizeof(S));
/* After some tests I found out how to access 'properly' the
* 'array':
*/
memcpy(array + 1, &s, sizeof(S); /* this will leave the first struct
in the 'array' unchanged and copy 's's contents to the second
element */
Same for memset(). So far I thought the indexing should be done manually, providing the size of the copied object as well, but no?
memcpy(destination + (size * offset), source + (size * offset), size)
Am I doing something wrong?
memcpy
and memset
are not the culprits in this case. Your problem comes from a misunderstanding of pointer arithmetic.
When you add a number to a pointer, the pointer advances by that many elements, not by that many bytes. So if sizeof(S) == 8
, then a pointer to an S
is advanced by 8 bytes when adding 1 to it, by 16 bytes when adding 2, and so on. The point is that you can abstract the bytes (and therefore the element's size) out of the picture.
So if you allocated an array of three S
elements, your memory might be laid out like so:
S
int
char
(bytes)You want to be able to ignore the bytes, and only access the x
and y
fields through an S
, so that leaves S
-sized blocks of memory.
|0 |1 |2 | array : S *
|x y |x y |x y | S[N]->x, S[N]->y : int *
|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7| individual bytes : char *