оказывается данный код в соответствии со стандартом. вызывает краш
...
free( p ) ;
if ( p == NULL ) // ..
|
оказывается данный код в соответствии со стандартом. вызывает краш
...
free( p ) ;
if ( p == NULL ) // ..
Уверяю вас, в стандарте ничего нет про крэш. Там есть undefined behavior, но здесь я его не вижу, если p - валидный указатель на память, выделенную malloc и иже с ними.
ну етого хватает - в мане про cake php - потенциальный инжекшон прописан .....
Sic Vis Pacem, Parra Bellum
Моя хата з найкращого краю в світі.
Могу вас уверить,
можно написать миллион выражений с ошибками с точки зрения здравого смысла, которые спокойно прокомпилируются.
И целые толмуды описывают, как этого не делать.
Обнулять указатель после освобождения - это классика!
Хотите поиграться, начните с этого:
void f()
{
f();
}
Обычная рекурсия без выхода. Программа завалится по переполнению
стека. Но с точки зрения компиляции - абсолютно грамотная конструкция.
так вроде бы 2 есть ошибки .... например на яве - на собеседовании задают вопрос .....что будет //// бла бла бла
и выбирай
compilation error
runtime error
Последний раз редактировалось Evilsun; 29.11.2007 в 04:19.
Sic Vis Pacem, Parra Bellum
Язык какой?
Если на С, то проблем нет и быть не может, вполне допустимая конструкция, хотя и бессмысленная семантически.
free(p) не меняет значение p и никак не влияет на способы доступа к p - меняется доступ к *p.
Приведи выдержку из стандарта где это указано, если это С конечно.
The future is already here - it is just unevenly distributed. (c) W. Gibson
C++, Stadard
3.7.3.2/4: "If the argument given to a deallocation function in the
standard library is a pointer that is not the null pointer value
(4.10), the deallocation function shall deallocate the storage
referenced by the pointer, rendering invalid all pointers referring to
any part of the deallocated storage. The effect of using an invalid
pointer value (including passing it to a deallocation function) is
undefined."
Все правильно и так же как и в С. В данном случае invalid pointer value - это не p, а *p.
И undefined effect будет если ты напишешь free(p); if(*p==NULL) ...
Не может free(p) поменять значение p.
Сравни с С:
IEEE Std 1003.1, 2004 Edition
The free() function shall cause the space pointed to by ptr to be deallocated; that is, made available for further allocation. If ptr is a null pointer, no action shall occur. Otherwise, if the argument does not match a pointer earlier returned by the calloc(), malloc(), [ADV] [Option Start] posix_memalign(), [Option End] realloc(), or [XSI] [Option Start] strdup() [Option End] function, or if the space has been deallocated by a call to free() or realloc(), the behavior is undefined.
Any use of a pointer that refers to freed space results in undefined behavior.
Последний раз редактировалось homo ludens; 03.12.2007 в 07:56. Причина: добавил цитату IEEE Std 1003.1, 2004 Edition
The future is already here - it is just unevenly distributed. (c) W. Gibson
имхо, нет там такого прикола.
"The effect of using an invalid pointer value (including passing it to a deallocation function) is undefined."
ничего такого не подразумевает, что шло бы в разрез с общепринятыми понятиями - после освобождения блока не стоит разименовывать указатель и повторно его передавать в free.
не понял.
что значит разименовывать указатель?
и кто его повторно передает в free()?
поясни.
разименовывать - использовать память на которую указатель указывает.
1. int* pint;
2. pint=(int*)malloc(sizoef(int));
3. *pint=a;
4. b=*pint;
5. free(pint);
вот если строка 5 будет перед 3ей - вот тогда поведение строк 3 и 4 - undefined
два раза вызвать free на одном указателе - так тоже иногда бывает в жизни. баг, есс-но, но бывает. и вот поведение повторного вызова free - undefined.
не об этом ли говорит стандарт?
то о чем вы пишите действительно тривиально, но это совершенно не имеет отношения к тому что я написал. еще раз
void *p = malloc(1);
free (p);
if (p==0) // здесь возникает UB
{
...
}
здесь нет разименовывания (как вы определили) , здесь нет повторного освобождения памяти.
и это я назвал приколом.
код free(p); if(!p) ... абсолютно законен с точки зрения стандарта.
незаконен код free(p); if(!*p)
В стандарте С написано более просто.
Any use of a pointer that refers to freed space results in undefined behavior.
А в С++ попробовали ужесточить и фраза стала чуть менее понятной.
The effect of using an invalid pointer value (including passing it to a deallocation function) is undefined.
Реально написано одно и тоже, только разными словами.
Можно конечно прикопаться к термину using /any use и сказать, что любое упоминание в тексте (включая комментарии) имени переменной, после ее освобождения по free есть UB.
Тогда твой пример действительно верен.
Я надеюсь, что авторы компиляторов все-таки не примут эту точку зрения, ну их нафиг такие приколы.
The future is already here - it is just unevenly distributed. (c) W. Gibson
если бы это было верно
free (p);
if (p==0) // здесь возникает UB
это бы подразумевало, что free модифицирует содержимое переменной p (банально, как области памяти в 4 байта для 32битных систем).
однако
free(void* p) этого сделать не может.
он должен быть либо free(void** p) либо free(void*& p) /а референсов в С, если не ошибаюсь, нет. между тем free - функция именно С-рунтайма, а не С++ /
Социальные закладки