Определение структуры в C с Malloc

Я задал вопрос раньше, определяющий структуру с помощью malloc. Это было ответом, который мне дало большинство:

struct retValue* st = malloc(sizeof(*st));

Я показывал другу свой код, и мы приехали в камень преткновения. Кто-то мог объяснить, почему этот код работает? С моей точки зрения *не был определен Св., когда Вы malloc это, таким образом, мог быть любой вид мусора там. Это должно быть malloc(sizeof(struct retValue))

Спасибо за любую справку

7
задан Community 23 May 2017 в 12:26
поделиться

4 ответа

Из документации по NSObject:

Среда выполнения отправляет инициализацию каждому класс в программе ровно один раз непосредственно перед классом или любым классом который наследует от него, отправляется его первое сообщение из программы. (Таким образом, метод никогда не может быть вызван если класс не используется.) Среда выполнения отправляет сообщение инициализации в классы в защищенном от потоков способе. Суперклассы получают это сообщение перед их подклассами. Метод

+ initialize вызывается только перед отправкой первого сообщения класса. До отправки сообщения в класс метод + initialize не вызывается.

Eg:

При вызове [[MyObject alloc] init]; , + initialize вызывается в MyObject непосредственно перед отправкой alloc в MyObject.

-121--3101628-

Обычно я использую VS2008, выполняющиеся на узле, с сборками SharePoint, установленными в GAC узла. Я использую события построения/цели построения с общей папкой и sysinternals для построения непосредственно в папках bin/GAC виртуальной машины SharePoint. Этот путь Visual Studio создаётся непосредственно на сервере SharePoint, и управление 2 установками (хостом и виртуальной машиной) не требуется. Для упрощения отладки рекомендуется также установить VS2008 отладчик в качестве службы на виртуальной машине.

Надеюсь, это поможет!

-121--5044559-

Размер взгляда на тип данного ему выражения, оно не оценивает выражение. Таким образом, нужно только убедиться, что переменные, используемые в выражении, объявлены так, чтобы компилятор мог вывести их тип.

В вашем примере st уже объявлен как pointer-to-struct-retValue. Следовательно, компилятор способен вывести тип выражения «* st».

Хотя не похоже, что он уже объявлен в вашем коде, компилятор уже позаботился о нем для вас. Все объявления в коде перемещаются в начало блока, в котором они появляются компилятором. Предположим, вы пишете

Один из способов проиллюстрировать знания, которые доступны компилятору, это посмотреть на промежуточные выходные данные, которые он генерирует. Рассмотрим этот пример кода...

struct retValue {long int a, long int b};
...
printf("Hello World!\n");
struct retValue* st = malloc(sizeof(*st));

Используя gcc в качестве примера и приведенный выше код в функции main () команды test.c , рассмотрим промежуточный выход, выполнив команду...

gcc -fdump-tree-cfg test.c

Компилятор создаст файл test.c.022t.cfg - Посмотрите на него и вы увидите

[ ... removed internal stuff ...]
;; Function main (main)

Merging blocks 2 and 3
main (argc, argv)
{
  struct retValue * st;
  int D.3097;
  void * D.3096;

  # BLOCK 2
  # PRED: ENTRY (fallthru)
  __builtin_puts (&"Hello World!"[0]);
  D.3096 = malloc (16);
  st = (struct retValue *) D.3096;
  D.3097 = 0;
  return D.3097;
  # SUCC: EXIT

}

Обратите внимание, как объявление было перемещено в начало блока, и аргумент malloc уже заменен фактическим значением, обозначающим размер типа, для которого вычисляется выражение. Как указано в комментариях, тот факт, что объявление было перемещено в верхнюю часть блока, является детализацией реализации компилятора. Однако тот факт, что компилятор способен сделать это, а также вставить правильный размер в маллок все показывает, что компилятор смог вывести необходимую информацию из ввода.

Я лично предпочитаю, чтобы фактическое имя типа в качестве параметра имело значение sizeof, но это, вероятно, вопрос стиля кодирования, где я бы сказал, что согласованность превышает личные предпочтения.

19
ответ дан 6 December 2019 в 05:06
поделиться

В C, размер является оператором, и не оценивает его аргумент. Это может привести к "интересным" эффектам, которые не всегда ожидаются новичком в Си. Я упоминал об этом более подробно в моем ответе на вопрос "Самая странная особенность языка".

0
ответ дан 6 December 2019 в 05:06
поделиться

Важно объявление/определение типа структуры, а не определение объекта такого класса. К тому времени, как Вы достигнете malloc, с декларацией/определением столкнется компилятор, в противном случае Вы столкнетесь с ошибкой компилятора.

Тот факт, что sizeof не оценивает свои операнды, является побочной проблемой.

Маленький нит: помните, что нам нужны скобки, когда мы поставляем имена типов к sizeof, как в:

sizeof(struct retValue);

, а не в случае с объектами, мы просто делаем:

sizeof *st;

Смотрите стандарт:

6.5. 3 Унарных оператора Syntax

unary-expression:
[...]
sizeof unary-expression
sizeof ( type-name )
1
ответ дан 6 December 2019 в 05:06
поделиться

Оператор sizeof на самом деле не оценивает свой операнд - он просто смотрит на его тип. Это делается во время компиляции, а не во время выполнения. Таким образом, это можно безопасно выполнить до присвоения переменной.

19
ответ дан 6 December 2019 в 05:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: