'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 experience 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
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 1:[1]
In order to serialize/deserialize, all you need to ensure is that there is sufficient space (so data elements aren't over written by each other ) and have the serialize() and deserialize() functions agree on the format. For your example, it could have been:
size_t serialize_row(Row *source, void *dest) {
return sprintf(dest, "(%s,%d,%s)", source->email, source->id, source->username);
}
int deserialize_row(void *source, Row *dest) {
int n;
n = sscanf(dest, "(%s,%d,%s)", source->email, &source->id, source->username);
return n == 3;
}
The order doesn't matter, the external form has no bearing on the internal form, and all that is important is managing the buffer & io-sizes. Note, btw, that if source->email or source->name contained a ), it could make this fail, so a more robust example is called for.
Solution 2:[2]
Because when you do serialization function, it doesn't matter how will you save it in the file or in the space of HEAP memory. You use as source exact address of each field and just use its size as amount of bytes. When you do deserialization function, it doesn't matter again because you just put all data consecutively and by hand and compiler(if it is necessary) will add padding to the end of the structure.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | mevets |
| Solution 2 | RobJob |
