2009-06-04 5 views
51

Я хотел спросить о следующем случае:Должен ли я явно указывать возвращаемое значение malloc()?

char *temp; 
temp = malloc(10); 

Поскольку тип возвращаемого malloc является void*, будет указатель, возвращаемый malloc быть неявно приведен к типу char* перед назначением температуры? Что говорит стандарт в этом отношении?

Если наша переменная указатель некоторый тип структура, например:

struct node *temp; 
temp = (struct node *)malloc(sizeof(struct node)); 

Если выделить память для температуры без приведения его к struct node* типа, он будет неявно приведен к struct node* типа или необходимо явно приводить это до struct node* типа?

+7

Если вам, возможно, понадобится скомпилировать код с компилятором C++, а не компилятором C, то требуется бросок. Следовательно, большая часть моего кода включает явное приведение - даже если чистый C не требует этого. Обычно я указываю его/* = C++ = * /, чтобы указать, почему. –

+0

Хотя это не обязательно, мне помогает прочитать код позже с небольшим количеством подробностей. – Xolve

+2

См. Также [этот вопрос] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858). – unwind

ответ

33

Указатель void в C может быть назначен любому указателю без явного приведения.

+9

Я не думаю, что это относится к указателям на функции. –

+11

C оставляет его неопределенным, можете ли вы указывать указатели функций на указатели нерабочих или назад. C++ явно запрещает его, а C++ 1x условно поддерживает его –

+10

И хотя POSIX (по крайней мере, 2008) требует, чтобы указатели на функции были того же размера, что и указатели данных, где стандарт C оставляет это неопределенным. –

10

C неявно отбрасывает от и до void*, поэтому литье будет выполнено автоматически. В C++ только преобразование вvoid* будет сделано неявно, для другого направления требуется явное литье.

+2

Примечание. C++ поддерживает преобразование в void * без трансляции. – 2009-06-04 21:15:10

3

В C++ вы должны явно использовать, но это действительно тот язык, который говорит вам об этом.
В c на самом деле нет необходимости бросать, память - это просто память - мне нужно будет выполнить поиск, чтобы узнать, требует ли его последний стандарт C.

+2

Стандарт C99 не требует отливки. –

49

Если вам нравится образ «не повторяйте себя», вам должно быть интересно, что вам не нужно повторять имя типа из объявления переменной в вызове malloc(). Потому что, как указывали люди, вы не указали: конвертеры конвертируются в и от void * без потерь, за исключением указателей на функции.

Также на этой ноте вам не нужно повторять себя с использованием sizeof. Ваш второй пример, при выделении структуры, можно записать так:

struct node *temp; 
temp = malloc(sizeof *temp); 

Что в моей не столь скромному мнению, является лучшим способом.

Избегание повторения себя сокращает количество вещей, которые вы пишете, что, в свою очередь, снижает риск того, что любая из этих вещей окажется неправильной.

Обратите внимание на звездочку в аргументе sizeof, это означает «размер объекта, на который указывает этот указатель», который, конечно, совпадает с размером «struct node», но без повторения имени типа. Это связано с тем, что sizeof вычисляет (во время компиляции!) Размер выражения, являющегося его аргументом. Для этого случая. Точно так же, как sizeof 3 вычисляет размер выражения типа int, sizeof *temp вычисляет размер экземпляра struct node.

Несомненно, вы повторяете что-то, то есть имя самой переменной, но это часто более простое выражение и легче получить право, а также может быть проще для компилятора обнаружить ошибку.

+6

+1 sizeof * temp – diapir

+3

Это один из примеров, когда применение DRY - это небезопасная практика программирования (см. Следующую ссылку). Аргумент, который избегает повторения, уменьшает ошибки, является контекстуальным. Когда дело доходит до указателей на C, столь печально известных для двусмысленности, это приведет к плохой джуджу. Я скорее буду многословным и повторю броски, чтобы найти проблемы во время компиляции (в отличие от времени выполнения): https://www.securecoding.cert.org/confluence/display/seccode/MEM02-C.+Immediately+cast+ + результат + of + a + память + распределение + функция + вызов + в + указатель + + + + выделенный + тип –

+3

Как обычно, securecoding.cert.org полон дерьма. Или, более вежливо, каждая статья, которую я прочитал на этом сайте, заполнена неверной информацией (подумайте о 'ftell' vs' fstat'), стиль, который широко согласен быть плохим и вредным, и/или просто грузо-культового «безопасности». –

Смежные вопросы