Это правильный путь:
Type *t = malloc(sizeof *t);
Почему это правильно?
Потому что вы правильно распределили размер, достаточный для размещения структуры. *t
указывает на тип Type
.
Это неверный способ:
Type *t = malloc(sizeof(t));
Почему это неверно?
sizeof(t)
возвращает размер указателя, а не фактический тип (т. Е. Не размер структуры).
Вы должны выделить достаточно большой размер, чтобы вместить структуру, а не размер, равный указателю на структуру.
Обратите внимание, что размер указателя, указывающего на Любой тип , одинаков в системе.
Почему первый подход лучше?
При первом подходе, когда вы изменяете Type
, malloc
автоматически меняет размер на правильное значение, вам не нужно делать это явно, в отличие от других способов.
Кроме того, важной частью написания вызова malloc
является поиск правильного размера, который необходимо передать. Лучший способ сделать это - не смотреть куда-либо (потому что именно тогда мы совершаем ошибку), а только в левой части этого оператора malloc
. Так как в этом случае это t
, следовательно, правильный размер будет sizeof(*t)
.
Как стандартизировать использование malloc
?
При вышеупомянутом правильном подходе есть одна проблема, скажем, если мы хотим malloc
сказать 30 elements
. Тогда наше malloc
выражение становится:
t = (T *) malloc(30 * sizeof (*T));
Это не предпочтительный способ записи выражения malloc
, потому что можно ошибиться, введя число 30
в параметре malloc
. Что бы мы хотели - независимо от количества требуемых элементов, параметр malloc
всегда должен быть стандартным sizeof(*x)
или чем-то подобным.
Итак, вот подход с примером:
Предположим, у нас есть указатель p
, указывающий на одномерный массив size 20
, каждый элемент которого равен struct node
. Декларация будет:
struct node (*p) [20];
Теперь, если мы хотим malloc
20 elements
из stuct node
и хотим, чтобы указатель p
содержал адрес возврата malloc
, тогда мы имеем
p = (data-type of p) malloc (size of 20 elements of struct node);
Чтобы найти тип данных p
, для приведения мы просто убираем имя переменной или заменяем p
пробелом. Итак, теперь у нас есть
p = (struct node (*)[20] ) malloc(size of 20 elements of struct node);
Мы не можем ошибаться, потому что компилятор будет жаловаться, если мы ошибаемся. Наконец-то размер! Мы просто делаем стандартный способ, который мы описали, то есть
p = (struct node (*)[20] ) malloc(sizeof (*p));
И мы закончили!