Поскольку buf
является указателем на char
, когда вы пишете (struct data *) (buf + offset)
, вы говорите: «Возьмите этот указатель на некоторый символ и сделайте его указателем на struct data
». Однако struct data
должно быть выровнено по кратности четырех байтов 1 , но ваш buf+offset
может иметь любое выравнивание.Если buf+offset
имеет неправильное выравнивание, не может быть превращено в правильный указатель на struct data
, и ваш компилятор сообщит вам об этой проблеме.
Решение состоит в том, чтобыу вас есть выровненный адрес, который можно использовать как указатель на struct data
.Это можно сделать двумя способами:
- Определить один или несколько
struct data
объектов, как с struct data MyData;
или struct data MyArray[10];
. - Выделить память для
struct data
объектов, какс struct data *MyPointer = malloc(SomeNumber * sizeof *MyPointer);
.
При любом из вышеперечисленных компилятор обеспечит правильное выравнивание памяти для объекта struct data
.Первый обычно используется только для немедленной работы с struct data
, а затем сбрасывает его - он не создает объект, который вы можете вернуть из функции.Последний используется, когда вы хотите вернуть полученный struct data
из функции.
Когда у вас есть эти struct data
объекты, вам необходимо поместить в них данные.Желательно, чтобы вы считывали данные непосредственно в них, а не в buf
.Однако, если ваш программный дизайн не облегчает это, вы можете скопировать данные из buf
в struct data
объекты, как с одним из:
memcpy(&MyData, buf+offset, sizeof MyData);
memcpy(MyArray, buf+offset, sizeof MyArray);
memcpy(MyPointer, buf+offset, SomeNumber * sizeof *MyPointer);
Сноска
1 Четыре типичны для структуры, содержащей int
, и предполагается для этого примера.Мы знаем, что требование выравнивания больше единицы из-за сообщения компилятора.