I created three buffers and variables and copied every variable to the according buffer.
Then I took the pointers from the buffer and printed it.
#include <stdlib.h>
#include <string.h>
int main() {
// Buffers.
unsigned char a_buffer[sizeof(int)];
unsigned char b_buffer[sizeof(int)];
unsigned char c_buffer[sizeof(float)];
// Variables ressources.
int a = 65500;
int b = 32000;
float c = 3.14;
// Variables pointers.
int *aa = NULL;
int *bb = NULL;
float *cc = NULL;
/* Copy variables to buffer. */
memcpy(a_buffer, &a, sizeof(int));
memcpy(b_buffer, &b, sizeof(int));
memcpy(c_buffer, &c, sizeof(float));
/* Set pointers. */
aa = (int*) a_buffer;
bb = (int*) b_buffer;
cc = (float*) c_buffer;
// Print values.
printf("%i %i %f\n", *aa, *bb, *cc);
return 0;
}
Output: 65500 32000 3.140000
Now I like to store these variables into one buffer and wrote this.
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
int main() {
// Buffer.
unsigned char buffer[sizeof(int) + sizeof(int) + sizeof(float)];
// Buffer pointer (first object).
unsigned char *buf_ptr = buffer;
// Variables ressources.
int a = 65500;
int b = 32000;
float c = 3.14;
// Variables pointers.
int *aa = NULL;
int *bb = NULL;
float *cc = NULL;
/* Copy variables to buffer. */
uint16_t cur = 0;
memcpy(buf_ptr + cur, &a, sizeof(int));
cur += sizeof(int);
memcpy(buf_ptr + cur, &b, sizeof(int));
cur += sizeof(int);
memcpy(buf_ptr + cur, &c, sizeof(float));
cur += sizeof(float);
/* Set pointers. */
cur = 0;
aa = (int*) buf_ptr + cur;
cur += sizeof(int);
bb = (int*) buf_ptr + cur;
cur += sizeof(int);
cc = (float*) buf_ptr + cur;
cur += sizeof(float);
// Print values.
printf("%i %i %f\n", *aa, *bb, *cc);
return 0;
}
Output: 65500 2054246226 0.000000
The first variable is correct, the second changes always, and the third is always zero.
What is the correct way to do it?
The short answer is that it looks like you're adding the wrong offset due to the pointer type when doing the aa = (int *)buf_ptr + cur
section.
Use aa = (int *)(buf_ptr + cur)
instead (and correspondingly for the other pointer assignments).
Here is an ideone that does this, looks like it works: https://ideone.com/64awsM
The reason is this: when you cast buf_ptr
to (int *)
, you're saying treat this as a pointer to an integer (which is what you want).
But then you add an offset cur
to that pointer, so if you were thinking of buf_ptr
as an array, you're accessing buf_ptr[cur]
where each element is an int
. Since you have cur=sizeof(int)
(which is probably 4 or 8), you are quickly leaving the range of your buffer. If you keep buf_ptr
as a char array, your offsets are single bytes as you expected, and you only perform the cast at the end.
This also explains why your first element was always correct (since you basically are doing buf_ptr[0]
, it doesn't matter what the element size is since the offset is zero).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With