Как уже говорилось, не стоит возвращать malloc()
в C, это бесполезно и может скрывать ошибки.
Кроме того, чтобы вычислить адрес, следующий за заголовком узла, я считаю более понятным сделать это следующим образом:
t->data = t + 1;
Это работает, потому что t
является типизированным указателем, поэтому арифметика на нем работает нормально. Добавление одного увеличивает его на размер указанных данных, то есть sizeof (Node)
в этом случае. Я нахожу это использование идиоматичным для этого конкретного случая вычисления адреса, следующего сразу за чем-то просто malloc()
ed (когда это «что-то» является четко определенным типом со статически известным размером, как структура Node
в этом случае, конечно).
Это имеет следующие преимущества:
- Нет повторения имени типа.
- Нет
sizeof
, так что короче.
- Опять же, нет актеров.
- Очень простая арифметика, легко читаемая.
Я понял, что при использовании типа Node
произошла ошибка до того, как он был должным образом объявлен. Я не согласен с решением Диркгентли, вот как оно должно выглядеть, в C:
/* This introduces the type name "Node", as an alias for an undefined struct. */
typedef struct Node Node;
struct Node {
Node *next; /* This is OK, the compiler only needs to know size of pointer. */
void *data;
};
Для полноты, и поскольку я не устаю показывать, как я считаю, код должен быть написан следующим образом, вот пример функции для создания нового узла для хранения n байтов данных:
Node * node_new(size_t n)
{
Node *node;
if((node = malloc(sizeof *node + n)) != NULL)
{
node->next = NULL;
node->data = node + 1;
}
return node;
}
Вот и все. Обратите внимание на использование sizeof
для цели указателя в вызове malloc()
, чтобы избежать повторения имени типа и создания легко забываемой зависимости, если тип когда-либо изменится.