2016-05-21 4 views
0

В реализации основного бассейна у меня есть что-то вроде этого (я буду упрощать код понятнее)Преобразование из пустоты * на символ * в реализации пула

struct unit_header{ 
    struct unit_header* next, prev; 
}; 
int number_of_units = 10 
int unit_size = 5; 
int full_block = number_of_units*(unit_size+sizeof(struct unit_header)); 

void* p_mem_full_block = malloc(full_block); 

//iterate all units of mem_full_block 
for (int i = 0; i< number_of_units; i++){ 
    //pointer to each unit 
    struct unit_header* p_units = (struct unit_header*)((char*)p_mem_full_block + i*(unit_size+sizeof(struct unit_header))); 
    //.... some pointers stuff.... 
} 

Я знаю, что это часть (ниже) используется, чтобы пройти через все подразделения mem_block ...

i * (unit_size+sizeof(struct unit_header)) 

Я не понял, что эта часть:

(символ *) p_mem_full_block

средства. Почему я должен сделать это преобразование char *?

+0

Возможно, это связано с тем, что указатель на указатель 'void' является незаконным, и вы пытаетесь добавить какое-то значение этому указателю. см. [this] (http://stackoverflow.com/questions/3523145/pointer-arithmetic-for-void-pointer-in-c) –

ответ

0

Это потому, что в соответствии со стандартом C вы не можете добавить, вычесть что-либо на void *; однако сложение и вычитание определены для char *, где они продвигают указатель по заданному числу байт.

Однако GCC допускает арифметику указателей void как расширение без предупреждений, если не разрешено -Wpointer-arith или -Wpedantic, или так.


Кроме того, вся операция не выглядит очень компактна в том, что в unit_header структурах может иметь требование к выравниванию, которые отличаются от кратных unit_size. Действительно, unit_size из 5 приведет к проблемам, и на многих процессорах такой код будет компилироваться, но сбой во время выполнения, потому что указатель (, next) смещен, например. для реализации может потребоваться адрес, делящийся на 4 или 8, тогда как код будет содержать любое число между ними. Однако сам x86 обычно не заботится о неправильном выравнивании.

I.e. Преобразование между двумя типами указателей приводит к некорректному выравниванию результата. имеет неопределенное поведение в соответствии с C11.

+0

Спасибо, человек. Вы спасли меня. :П – PescadorParrudo

Смежные вопросы