Понимание переменной со структурами и указателями в C - PullRequest
0 голосов
/ 13 октября 2018

Я не знаю, что означает следующее назначение:

struct reportItem * itemCopy = (struct reportItem *) malloc(sizeof(struct reportItem))

Может ли кто-нибудь объяснить мне это назначение шаг за шагом?Я действительно не знаю, что это значит.

Спасибо

Ответы [ 3 ]

0 голосов
/ 13 октября 2018
struct reportItem *itemCopy = (struct reportItem *) malloc(sizeof(struct reportItem));
//                            ^^^^^^^^^^^^^^^^^^^^^

Приведение является ненужным и может скрыть ошибку, которую компилятор мог бы обнаружить при его отсутствии (1)

struct reportItem *itemCopy = malloc(sizeof(struct reportItem));
//                                         ^^^^^^^^^^^^^^^^^^^

Использование самого типа здесь может рассматриваться как "авария, ожидающая случиться""(2).Безопаснее использовать сам объект

struct reportItem *itemCopy = malloc(sizeof *itemCopy);

Так что теперь это хорошо выглядящий оператор:)

Это вызывает библиотечную функцию malloc() (которая пытается зарезервировать область памяти дляиспользуемую программу) и присваивает результирующее значение itemCopy.

Ответственность программиста - проверить, удалось ли malloc() зарезервировать память до , используя эту память.

if (itemCopy == NULL) {
    //malloc failed to reserve memory
    fprintf(stderr, "no memory.\n");
    exit(EXIT_FAILURE);
}

Кроме того, программист отвечает за освобождение памяти (обратно в ОС), когда эта память больше не требуется.

//use itemCopy
free(itemCopy);

(1) ошибка скрытия приведения

Если в области действия malloc() нет прототипа, компилятор предполагает, что он возвращает int.Затем с помощью приведения молча преобразует этот недопустимый int (недопустимый, потому что это, по сути, значение void*) в указатель. Ошибка в отсутствии #include <stdio.h> и приведении .Если вы просто удалите приведение, компилятор пожалуется на преобразование из int в указатель.Если вы #include <stdio.h> и сохраняете приведение, он является избыточным (а избыточный - плохим).

(2) использование типа для определения количества выделяемой памяти - это «ожидающая авария»

Вызов malloc(sizeof(struct whatever)) - это «случайность, которая должна произойти», потому что он заставляет программиста изменять код более чем в одном месте с одним изменением структуры.

Давайте представим, что есть struct Car с некоторыми свойствами... Позже было решено изменить часть кода на новый обновленный struct Vehicle (при этом struct Car оставался активным).Использование имени типа в вызове malloc() вызывает 2 изменения

struct Vehicle *x = malloc(sizeof (struct Vehicle));
//                                ^^^^^^^^^^^^^^^^ prevented accident

, тогда как для использования объекта требуется всего одно изменение

struct Vehicle *x = malloc(sizeof *x);
//                                ^^ *x is of the correct type 
0 голосов
/ 13 октября 2018

sizeof (struct reportItem) возвращает размер, принятый типом данных struct reportItem

malloc выделяет запрошенные байты в этом случае независимо от того, что возвращает sizeof (struct reportItem)

(struct reportItem *) используется для ввода значения, возвращаемого функцией malloc.Однако это не требуется, вы можете проверить это больше, нужно ли приводить malloc?

struct reportItem * ItemCopy тогда назначается базовый адрес приведенной фиксированной памяти такого размеразанято reportItem.

0 голосов
/ 13 октября 2018

struct reportItem - это тип структуры, который был ранее объявлен.Структура в C в основном представляет собой блок данных, который можно прочитать по частям, где каждая часть имеет тип и имя.Первая часть объявляет указатель itemCopy, который является просто переменной, хранящей адрес памяти.struct reportItem просто сообщает компилятору, что данные по этому адресу памяти должны интерпретироваться как структура reportItem.malloc - это функция, которая выделяет память для хранения вещей.Вы сообщаете ему, сколько байт памяти вам нужно, и он возвращает указатель, содержащий адрес первого байта этой вновь выделенной памяти.sizeof возвращает размер в байтах объекта или типа объекта.В этом случае он выделяет достаточно памяти для хранения одной reportItem структуры.Указатель, возвращаемый из malloc, затем преобразуется в объявленный тип указателя, и itemCopy назначается для хранения этого адреса.

...