Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why the layout of holding of structure in memory doesnt matter for serialization/deserialization functions in C programming

I am new at C programming. I wanted to comprehend structure of DB to get new expirience in programming and CS. So I started writing and right now I am at third section https://cstack.github.io/db_tutorial/parts/part3.html

Question:
So there is snippet of code where OFFSET of field of structure are written

typedef struct {
    
    uint32_t id;
    char username[32];
    char email[255];

} Row;

#define size_of_attribute(Struct, Attribute) sizeof(((Struct*)0)->Attribute)

const uint32_t ID_SIZE = size_of_attribute(Row, id);
const uint32_t USERNAME_SIZE = size_of_attribute(Row, username);
const uint32_t EMAIL_SIZE = size_of_attribute(Row, email);
const uint32_t ID_OFFSET = 0;
const uint32_t USERNAME_OFFSET = ID_OFFSET + ID_SIZE;
const uint32_t EMAIL_OFFSET = USERNAME_OFFSET + USERNAME_SIZE;
const uint32_t ROW_SIZE = ID_SIZE + USERNAME_SIZE + EMAIL_SIZE;

and after that the author wrote serialization function

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

void serialize_row(Row *source, void *destination){

    memcpy(destination + ID_OFFSET , &(source->id) , ID_SIZE );
    memcpy(destination + USERNAME_OFFSET, &(source->username),USERNAME_SIZE);
    memcpy(destination + EMAIL_OFFSET, &(source->email),EMAIL_SIZE);

    return;
}

But I know that structure can be saved in the RAM not consecutively,
because compiler seeks to hold data in the size of power of 2(not only compiler). Anyways, for first element it will work because first element are required to be placed at once,but subsequent fields can be not after first field at once(there can be free spaces). It means that just USERNAME_OFFSET or EMAIL_OFFSET won’t work.

Please explain to me that.

I am using Manjaro linux(OS)

gcc(compiler)

gdb(debugger)

>Solution :

Yes, exactly, you are right, and your suspicions are right. There is no guarantee that struct members are consecutive, there may be padding between struct members and the code does not handle that.

Specially for that reason, there exists offsetof macro https://en.cppreference.com/w/c/types/offsetof .

Also, initializing a const with a value of another const is not part of C language, and is supported as an extension. In C, you have to repeat it (or use macros, as they expand).

Also, you should prefer to use size_t, not uint32_t, to represent sizes and indexes.

const size_t ID_OFFSET = offsetof(Row, id);
const size_t USERNAME_OFFSET = offsetof(Row, username);
const size_t EMAIL_OFFSET = offsetof(Row, email);
const size_t ROW_SIZE = sizeof(Row);

compiler seeks to hold data in the size of power of 2(not only compiler)

Hm, it’s not always size of 2, it’s aligned to alignof(type), which varies with type. So char does not need any adjustment, it can be anywhere, but long is usually aligned to 4 bytes. You may want to read http://www.catb.org/esr/structure-packing/ .

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading