2016-10-02 3 views
5

Я пишу код, как это:Является ли ptr = бесплатным (ptr), NULL безопасным?

#include <stdlib.h> 

int main(void) 
{ 
    void *kilobyte; 
    kilobyte = malloc(1024); 
    kilobyte = NULL, free(kilobyte); 
    return 0; 
} 

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

In the C and C++ programming languages, the comma operator (represented by the token ,) is a binary operator that evaluates its first operand and discards the result, and then evaluates the second operand and returns this value (and type).


Edit: перепутал заказ. Теперь он компилируется на gcc без каких-либо предупреждений.

+0

'free' не возвращает значение, поэтому линия является плохим. Код даже не печатает, используйте стандартный идеом. – Olaf

+0

AFAIK, оператор запятой сбрасывает значение 'free', которое является' void', и вместо этого использует 'NULL'. И это ** ** менее печатается, если ваш стиль требует последовательного назначения указателей на NULL после их освобождения. –

+0

Нет значения, чтобы отказаться! Вы пытались скомпилировать это, прежде чем спрашивать? Вы нашли доказательство в стандарте, это законно или незаконно? Просьба привести этот раздел. (о, и я попытался с gcc). – Olaf

ответ

11

Делая это:

kilobyte = NULL, free(kilobyte); 

У вас есть утечка памяти.

Вы установили kilobyte в NULL, поэтому любая память, на которую она указывала, больше не ссылается нигде. Затем, когда вы делаете free(kilobyte), вы эффективно делаете free(NULL), который не выполняет никаких операций.

Относительно free(NULL), от C standard.

7.22.3.3 The free function

1.

#include <stdlib.h> 
void free(void *ptr); 

2. The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc , the behavior is undefined.

Что касается исходного кода перед редактированием:

kilobyte = free(kilobyte), NULL; 

Проблема с этим состоит в том, что оператор = имеет более высокий приоритет, чем оператор ,, так это утверждение эффективно:

(kilobyte = free(kilobyte)), NULL; 

Это попытка установить переменную void, которая не допускается.

То, что вы, вероятно, с отступом, чтобы сделать это:

kilobyte = (free(kilobyte), NULL); 

Это освобождает указатель, затем устанавливает указатель на NULL.

Как отметил Олафа в комментариях, а не делать все в одной строке, было бы предпочтительнее, чтобы сделать это вместо:

free(kilobyte); 
kilobyte = NULL; 

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

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