LINUX.ORG.RU

Навеяно свежей дырой в Xorg

 , ,


9

7

Привет, ЛОР!

Ты, наверное, уже видел свежую дыру в Xorg, патч для которой выглядит буквально вот так:

-        else
+        else {
             free(to->button->xkb_acts);
+            to->button->xkb_acts = NULL;
+        }

В связи с этим у меня возник вопрос: а почему в стандартной библиотеке C нет макроса SAFE_FREE()?

#define SAFE_FREE(ptr) do{free(ptr);(ptr)=NULL;}while(0)

Напомню, что значение указателя после вызова free() является неопределённым согласно стандарту. Не только значение памяти, на которое он указывает, но и значение самого указателя, и работа с ним представляет собой жуткое undefined behaviour, а значит единственное что можно сделать – занулить его.

Так вот, почему даже таких банальных вещей нет? Я уже не говорю про строковый тип, а то даже Эдичка тут строки не осилил.

Моя гипотеза тут: C – это язык культа страданий во имя страданий.

Ответ на: комментарий от bugfixer

На правильную. В ней на странице 502:

J.2 Undefined behavior
...
- The value of a pointer that refers to space deallocated by a call to the free or realloc function is used (7.20.3).

То есть нельзя использовать значение указателя, ссылающегося на место, попавшее в free или realloc.

monk ★★★★★
()
Ответ на: комментарий от monk

То есть нельзя использовать значение указателя, ссылающегося на место, попавшее в free или realloc.

Вынужден признать что Вы таки правы: имел возможность пообщаться с одним из C++ committee members, и Ваша интерпретация этого параграфа это именно то что они имели в виду - нельзя pointer использовать после free(), от слова совсем. Более того - в плюсовом мире это же справедливо для delete. И более того - это же справедливо для случая когда pointer показывает куда-то на стек и это что-то gets destroyed. Мне это всё пока на голову не налезает, но мне (а) обещали показать внутреннюю переписку и документы «комитетчиков» проливающие свет на то как они «докатились до жизни такой» (если никто из комитета не будет против, и не факт что опубликовать смогу, но «своими словами» перескажу так точно), и (б) сказали что вроде как в gcc конкретно на этот UB подвязок пока нет, а вот в clang «уже» (какое счастье что мы clang для прод сборок не используем [пока]). В общем: снимаю шляпу - «век живи - век учись»…

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

обещали показать внутреннюю переписку и документы «комитетчиков» проливающие свет на то как они «докатились до жизни такой»

Логика за этим решением понятна. Сразу после free/delete/realloc компилятор вправе переиспользовать место под указателем, экономя несколько байт на стеке. Возможно ещё какие-то оптимизации.

monk ★★★★★
()
Ответ на: комментарий от bugfixer

Более того - в плюсовом мире это же справедливо для delete.

В плюсовом мире invalid pointer value, и там всё, кроме применения * и удоления, implementation-defined.

И более того - это же справедливо для случая когда pointer показывает куда-то на стек и это что-то gets destroyed.

Destroyed недостаточно.

utf8nowhere ★★★
()
Последнее исправление: utf8nowhere (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.