В этом коде, почему sizeof(x)
размер указателя, а не размер x
?Почему sizeof (type) размер указателя, а не размер самого типа?
typedef struct {
...
} x;
void foo() {
x *x = malloc(sizeof(x));
}
В этом коде, почему sizeof(x)
размер указателя, а не размер x
?Почему sizeof (type) размер указателя, а не размер самого типа?
typedef struct {
...
} x;
void foo() {
x *x = malloc(sizeof(x));
}
Поскольку C говорит:
(C99, 6.2.1p7) "Any other identifier has scope that begins just after the completion of its declarator."
Таким образом, в вашем примере, область объекта x
начать сразу после x *x
:
x *x = /* scope of object x starts here */
malloc(sizeof(x));
Чтобы убедить себя, поставить еще один объект декларации типа x
сразу после объявления объекта x
: вы получите сообщение об ошибке:
void foo(void)
{
x *x = malloc(sizeof(x)); // OK
x *a; // Error, x is now the name of an object
}
В противном случае, как отмечает Шахбаз в комментариях к другому ответу, это по-прежнему неправильное использование malloc
. Вы должны позвонить malloc
так:
T *a = malloc(sizeof *a);
и не
T *a = malloc(sizeof a);
Это потому, что sizeof(x)
использует сокровенное определение x
, который является указателем. Чтобы избежать этой проблемы, не используйте одно и то же имя для типа и переменной.
Кроме того, с помощью malloc используйте его следующим образом: 'type * var = malloc (sizeof (* var));' вместо 'malloc (sizeof (type))' – Shahbaz
Причиной рекомендации Shahbaz является то, что это означает, что тип из 'var' может измениться, и ваш код по-прежнему будет правильным. Если вы используете 'type' вместо' var * ', тогда вы должны помнить об изменении' type' в декларации и в 'sizeof'. –
Это плохая идея, чтобы не дать разные вещи разные имена (не только в программировании):
Академическое причина обозреватель поведения уже упомянул мои дорогие коллеги-аннотаторы.
Чтобы дать ясно советует имя diffenet вещи Differnet (здесь: типы переменных и переменных экземпляров):
typedef struct {
...
} X;
void foo() {
X *x = malloc(sizeof(X));
}
Еще более гибкий способ закодировать этот пример будет (как и уже упомянутый комментарий Shahbaz в):
typedef struct {
...
} X;
void foo() {
X *x = malloc(sizeof(*x));
}
последний пример позволяет изменить тип x
без изменения кода делает распределение.
Недостатком этого подхода является то, что вы можете переключиться с использования ссылок на массивы и стихи vica (как тип для x
), не будучи уведомленным компилятором и нарушающим ваш код.
Ваш вопрос не имеет отношения к 'malloc'. С немного здравым рассудком ваш вопрос: «Что такое' x'? –
@JensGustedt: Ну, да - однако, не 'sizeof' * в основном * используется вместе с' malloc'? – thejh
Это не имеет никакого отношения к 'sizeof'. Как я уже сказал, ваш вопрос: «Что такое' x'? или даже более понятным ", какой из двух« х »я получу здесь, тип или переменная указателя?» –