0

I am currently working on a personal project. It is a portable key/value database written in C. link project

However, I'm going through a big problem, I can't in any way serialize a struct to write to a file with file_descriptor. Example: This works perfectly

memcpy(destination, 10, sizeof(uint32_t));
ssize_t bytes_written = write(fd, destination, sizeof(uint32_t));

However, I need to serialize a struct that contains array of structs inside it:

typedef struct Row {
    uint32_t id;
    char username[COLUMN_USERNAME_SIZE + 1];
    char email[COLUMN_EMAIL_SIZE + 1];
} Row;

typedef struct Page {
    int leaf;
    int elems;
    int current_address_memmory;
    struct Row* info[MAX_ELEMENTS];
    int childs[MAX_ELEMENTS + 1];
} Page;

And I tried it like this:

void static 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);
}

void static serialize(Page* source, void* destination) {
    memcpy(destination + LEAF_OFFSET, &(source->leaf), LEAF_SIZE);
    memcpy(destination + ELEMS_OFFSET, &(source->elems), ELEMS_SIZE);
    memcpy(destination + ADDRESS_MEMMORY_OFFSET, &(source->current_address_memmory), ADDRESS_MEMMORY_SIZE);

    off_t initial_serialize_info = destination + ADDRESS_MEMMORY_OFFSET + ADDRESS_MEMMORY_SIZE;
    for(uint32_t index_info = 0; index_info < source->elems; index_info++) {
        void *row_serialize = malloc(sizeof(Row)); 
        serialize_row(&source->info[index_info], row_serialize);
        source->info[index_info] = row_serialize;

        memcpy(initial_serialize_info, source->info, sizeof(source->info));
        initial_serialize_info += sizeof(source->info);
    }
}

const size_t OFFSET_PAGE = sizeof(Page); 
void *serialized_page = malloc(OFFSET_PAGE);
serialize(page, serialized_page);
ssize_t bytes_written = write(fd, serialized_page, OFFSET_PAGE);

But the problem I'm facing is that the file in which I write the serialized struct, has random data that doesn't match the serialized struct... Something like this:

...........

If I give the command xxd -b file.db the output is this:

00005dc0: 00000000 00000000 00000000 00000000 00000000 00000000  ......
00005dc6: 00000000 00000000 00000000 00000000 00000000 00000000  ......
00005dcc: 00000000 00000000 00000000 00000000 00000000 00000000  ......
00005dd2: 00000000 00000000 00000000 00000000 00000000 00000000  ......
00005dd8: 00000000 00000000 00000000 00000000 00000000 00000000  ......
00005dde: 00000000 00000000 00000000 00000000 00000000 00000000  ......
00005de4: 00000000 00000000 00000000 00000000 00000000 00000000  ......
00005dea: 00000000 00000000 00000000 00000000 00000000 00000000  ......
  • 1
    Check this: https://stackoverflow.com/questions/16543519/serialization-of-struct – Agrudge Amicus Apr 30 '22 at 03:16
  • `memcpy(initial_serialize_info, source->info, sizeof(source->info));` is a problem. `initial_serialize_info` is an `off_t`, not a pointer, so it's not valid to pass it to `memcpy`. And that line copies the entire array of pointers, which is not at all what you need to do there. You need to copy the row data, not the array of pointers. Pointers cannot be part of serialized data. – user3386109 Apr 30 '22 at 04:01
  • Write (google & copy-paste) a hex dump function and hexdump the buffers you `write`. – hyde Apr 30 '22 at 07:44
  • Also, check IO return values and use eg. `perror` if there is an error. – hyde Apr 30 '22 at 07:45

0 Answers0