Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy variables into one buffer and read it

Tags:

c

buffer

store

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?

like image 981
clausismus Avatar asked Oct 31 '22 17:10

clausismus


1 Answers

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).

like image 64
neocpp Avatar answered Nov 15 '22 05:11

neocpp