Как заполнить структуру C из char * и выделить дополнительную память - PullRequest
0 голосов
/ 01 августа 2020

Я новичок в C.

У меня есть этот typedef и макрос fldsiz ():

typedef struct _zend_file_cache_metainfo {
    char         magic[8];
    char         system_id[32];
    size_t       mem_size;
    size_t       str_size;
    size_t       script_offset;
    uint32_t     checksum;
} zend_file_cache_metainfo;

#ifndef fldsiz
#define fldsiz(name, field) \
            (sizeof(((name*)0)->field))
#endif

В файле. c я уже читал некоторые данные в char * mydata.

Теперь я хочу взять содержимое mydata и заполнить структуру zend_file_cache_metainfo (переменная с именем info) некоторым из этого содержимого, а затем выделить память, продиктованную info.mem_size + info.str_size элементы структуры, а затем, наконец, скопируйте остальную часть mydata во вновь выделенную память.

Я не уверен в следующем:

  • мое использование memcpy ()
  • есть ли лучший способ «заполнить» информационную структуру?

zend_persistent_script *script;
zend_file_cache_metainfo info;
void *mem, *checkpoint, *buf;
int ok;

// Initialize empty structure
zend_file_cache_metainfo info = {0};

int length_magic = fldsiz(zend_file_cache_metainfo, magic) / 1;
int length_system_id = fldsiz(zend_file_cache_metainfo, system_id) / 1;
int length_mem_size = fldsiz(zend_file_cache_metainfo, mem_size) / sizeof(size_t);
int length_str_size = fldsiz(zend_file_cache_metainfo, str_size) / sizeof(size_t);
int length_script_offset = fldsiz(zend_file_cache_metainfo, script_offset) / sizeof(size_t);
int length_checksum = fldsiz(zend_file_cache_metainfo, checksum) / sizeof(uint32_t);

int offset_magic = 0;
int offset_system_id = length_magic;
int offset_mem_size = length_magic + length_system_id;
int offset_str_size = length_magic + length_system_id + length_mem_size;
int offset_script_offset = length_magic + length_system_id + length_mem_size + length_str_size;
int offset_checksum = length_magic + length_system_id + length_mem_size + length_str_size + length_script_offset;
int offsetData = offset_checksum + length_checksum;

// Fill info.magic
memcpy(info.magic, mydata + offset_magic, length_magic);
info.magic[length_magic - 1] = 0; // Ensure termination

// Fill info.system_id
memcpy(info.system_id, mydata + length_magic, length_system_id);
info.system_id[length_system_id - 1] = 0; // Ensure termination

// Fill info.mem_size + info.str_size + info.checksum - **Is this correct ?**
memcpy(info.mem_size, mydata + offset_mem_size, length_mem_size);
memcpy(info.str_size, mydata + offset_str_size, length_str_size);
memcpy(info.script_offset, mydata + offset_script_offset, length_script_offset);
memcpy(info.checksum, mydata + offset_checksum, length_checksum);

// Do some checks (omitted for brevity)

checkpoint = zend_arena_checkpoint(CG(arena));

    // Allocate memory
#ifdef __SSE2__
    /* Align to 64-byte boundary */
    mem = zend_arena_alloc(&CG(arena), info.mem_size + info.str_size + 64);
    mem = (void*)(((zend_uintptr_t)mem + 63L) & ~63L);
#else
    mem = zend_arena_alloc(&CG(arena), info.mem_size + info.str_size);
#endif

// Copy rest of mydata var into mem var - **Is this correct ?**
memcpy(&mem, mydata + offsetData, info.mem_size + info.str_size);

// Verify checksum (omitted for brevity)
...