Пара вещей:
Во-первых,
int *amount = 9;
не делает то же самое, что
*amount = 9;
В первом случае, *
только там, чтобы указать, что amount
имеет тип указателя, и мы инициализируем значение pointer (т. е. адрес) в 9
, который, скорее всего, не является допустимым значением указателя, и пытаемсяразыменование может привести к ошибке во время выполнения.
Во втором случае мы присваиваем целочисленное значение 9
объекту, на который указывает amount
.
Почему это не сломалось, когда вы передали amount
в printf
?По сути, вы вызывали неопределенное поведение, передавая аргумент неправильного типа (%d
ожидает int
, вы передали int *
).Одним из возможных результатов неопределенного поведения является получение ожидаемого результата.По какой-то причине printf
смог обработать это значение int *
как int
.Большинство компиляторов должны отмечать это несоответствие типов, но вам может понадобиться проверить уровень предупреждения, чтобы увидеть его.
Существует ограничение на двоичный оператор *
, согласно которому оба операнда имеют арифметический тип.int *
не является арифметическим типом, следовательно, является диагностическим.
Исходя из того, как вы на самом деле используете amount
в своем коде, вы должны были объявить его не как указатель, а как обычный int
:
int amount = 9;
Во-вторых, как правило, вы не хотите присваивать результат realloc
исходному указателю.Если realloc
завершится неудачно, он вернет NULL
и оставит исходный блок памяти как есть.Однако, если вы вернете этот NULL
к исходному указателю, вы потеряете доступ к этой памяти.Рекомендуется присваивать результат realloc
временному объекту, а затем убедиться, что временный объект действителен, прежде чем присвоить его обратно оригиналу:
int *tmp = realloc( array, amount * sizeof *array );
if ( tmp )
{
array = tmp;
}
else
{
// handle realloc error
}
Обратите внимание на использование sizeof *array
вместо sizeof (int)
.sizeof
является оператором, подобным унарному *
или унарному +
, и его операндом может быть имя типа в скобках или выражение. выражение *array
имеет тип int
, поэтому sizeof *array == sizeof (int)
.Это помогает немного облегчить чтение кода, и если вы когда-нибудь измените тип array
(скажем, double *
), вам не придется обновлять вызов realloc
.Это также очень полезно при распределении типов многомерных массивов - вы бы предпочли написать
int (*arr)[10] = malloc( sizeof (int) * 10 * rows);
или
int (*arr)[10] = malloc( sizeof *arr * rows );
?