Тема: век живи, век учись...

Ответить в теме
Страница 1 из 4 1 2 3 ... ПоследняяПоследняя
Показано с 1 по 20 из 67
  1. Вверх #1
    Не покидает форум Аватар для Ull9
    Пол
    Мужской
    Адрес
    Мюнхен
    Сообщений
    19,028
    Репутация
    1489

    Unhappy век живи, век учись...

    оказывается данный код в соответствии со стандартом. вызывает краш
    ...
    free( p ) ;
    if ( p == NULL ) // ..


  2. Вверх #2
    Частый гость Аватар для valheru
    Пол
    Мужской
    Адрес
    Одесса
    Возраст
    47
    Сообщений
    829
    Репутация
    56
    Уверяю вас, в стандарте ничего нет про крэш. Там есть undefined behavior, но здесь я его не вижу, если p - валидный указатель на память, выделенную malloc и иже с ними.

  3. Вверх #3
    Новичок Аватар для Evilsun
    Пол
    Мужской
    Сообщений
    96
    Репутация
    28
    ну етого хватает - в мане про cake php - потенциальный инжекшон прописан .....
    Sic Vis Pacem, Parra Bellum

  4. Вверх #4
    Постоялец форума Аватар для Newton
    Пол
    Мужской
    Адрес
    Calgary, Alberta
    Сообщений
    1,105
    Репутация
    825
    Цитата Сообщение от Ull9 Посмотреть сообщение
    оказывается данный код в соответствии со стандартом. вызывает краш
    ...
    free( p ) ;
    if ( p == NULL ) // ..
    Думаю тут не в стандарте дело, просто неграмотно написанный код.
    Должно быть вот так:
    Код:
    ....
    if (p) 
    {
          free(p);
          p = NULL;
    }
    .....
    if (p == NULL)....
    Можно придумать и другие варианты, например safe pointers со счетчиком ссылок, кому как нравится...
    Моя хата з найкращого краю в світі.

  5. Вверх #5
    Не покидает форум Аватар для Ull9
    Пол
    Мужской
    Адрес
    Мюнхен
    Сообщений
    19,028
    Репутация
    1489
    Цитата Сообщение от Newton Посмотреть сообщение
    Думаю тут не в стандарте дело, просто неграмотно написанный код.
    Должно быть вот так:
    Код:
    ....
    if (p) 
    {
          free(p);
          p = NULL;
    }
    .....
    if (p == NULL)....
    Можно придумать и другие варианты, например safe pointers со счетчиком ссылок, кому как нравится...
    в каком смысле неграмотный код?
    компилятор его компилит, значит там грамматических ошибок нет.
    да конечно в стандарте креша нет, как понятия, но это
    именно UB.
    обрашение к инвалидному пинтеру - это UB.

    а так как предлагается исправить, то да UB не будет.

  6. Вверх #6
    Цитата Сообщение от Ull9 Посмотреть сообщение
    в каком смысле неграмотный код?
    компилятор его компилит, значит там грамматических ошибок нет.
    Могу вас уверить,
    можно написать миллион выражений с ошибками с точки зрения здравого смысла, которые спокойно прокомпилируются.
    И целые толмуды описывают, как этого не делать.
    Обнулять указатель после освобождения - это классика!

    Хотите поиграться, начните с этого:
    void f()
    {
    f();
    }

    Обычная рекурсия без выхода. Программа завалится по переполнению
    стека. Но с точки зрения компиляции - абсолютно грамотная конструкция.

  7. Вверх #7
    Новичок Аватар для Evilsun
    Пол
    Мужской
    Сообщений
    96
    Репутация
    28
    так вроде бы 2 есть ошибки .... например на яве - на собеседовании задают вопрос .....что будет //// бла бла бла
    и выбирай
    compilation error
    runtime error
    Последний раз редактировалось Evilsun; 29.11.2007 в 04:19.
    Sic Vis Pacem, Parra Bellum

  8. Вверх #8
    Не покидает форум Аватар для Ull9
    Пол
    Мужской
    Адрес
    Мюнхен
    Сообщений
    19,028
    Репутация
    1489
    Цитата Сообщение от lexar Посмотреть сообщение
    Обнулять указатель после освобождения - это классика!
    .
    обнулять пойнтер после освобождения конечно надо, но зачем.
    лично для меня крэш здесь неожиданность.
    я же непытаюсь вызвать метод по этому пойнтеру, или прочесть поле. я всего лишь сравнивваю с нулем!

    я например этого незнал.

  9. Вверх #9
    Частый гость Аватар для homo ludens
    Пол
    Мужской
    Сообщений
    751
    Репутация
    141
    Язык какой?
    Если на С, то проблем нет и быть не может, вполне допустимая конструкция, хотя и бессмысленная семантически.
    free(p) не меняет значение p и никак не влияет на способы доступа к p - меняется доступ к *p.
    Приведи выдержку из стандарта где это указано, если это С конечно.
    The future is already here - it is just unevenly distributed. (c) W. Gibson

  10. Вверх #10
    Не покидает форум Аватар для Ull9
    Пол
    Мужской
    Адрес
    Мюнхен
    Сообщений
    19,028
    Репутация
    1489
    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."

  11. Вверх #11
    Частый гость Аватар для homo ludens
    Пол
    Мужской
    Сообщений
    751
    Репутация
    141
    Все правильно и так же как и в С. В данном случае 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

  12. Вверх #12
    Не покидает форум Аватар для Ull9
    Пол
    Мужской
    Адрес
    Мюнхен
    Сообщений
    19,028
    Репутация
    1489
    Цитата Сообщение от homo ludens Посмотреть сообщение
    Все правильно и так же как и в С. В данном случае invalid pointer value - это не p, а *p.
    И undefined effect будет если ты напишешь free(p); if(*p==NULL) ...
    а так же UB будет если написать

    free (p);
    if (p==0)
    {
    ...
    }

    в этом то и весь прикол.

  13. Вверх #13
    Постоялец форума Аватар для Guffy
    Пол
    Мужской
    Адрес
    Одесса
    Возраст
    49
    Сообщений
    1,356
    Репутация
    256
    имхо, нет там такого прикола.

    "The effect of using an invalid pointer value (including passing it to a deallocation function) is undefined."
    ничего такого не подразумевает, что шло бы в разрез с общепринятыми понятиями - после освобождения блока не стоит разименовывать указатель и повторно его передавать в free.

  14. Вверх #14
    Не покидает форум Аватар для Ull9
    Пол
    Мужской
    Адрес
    Мюнхен
    Сообщений
    19,028
    Репутация
    1489
    не понял.
    что значит разименовывать указатель?
    и кто его повторно передает в free()?
    поясни.

  15. Вверх #15
    Постоялец форума Аватар для Guffy
    Пол
    Мужской
    Адрес
    Одесса
    Возраст
    49
    Сообщений
    1,356
    Репутация
    256
    разименовывать - использовать память на которую указатель указывает.
    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.

    не об этом ли говорит стандарт?

  16. Вверх #16
    Не покидает форум Аватар для Ull9
    Пол
    Мужской
    Адрес
    Мюнхен
    Сообщений
    19,028
    Репутация
    1489
    Цитата Сообщение от Guffy Посмотреть сообщение
    разименовывать - использовать память на которую указатель указывает.
    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
    {
    ...
    }

    здесь нет разименовывания (как вы определили) , здесь нет повторного освобождения памяти.

    и это я назвал приколом.

  17. Вверх #17
    Частый гость Аватар для homo ludens
    Пол
    Мужской
    Сообщений
    751
    Репутация
    141
    код 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

  18. Вверх #18
    Не покидает форум Аватар для Ull9
    Пол
    Мужской
    Адрес
    Мюнхен
    Сообщений
    19,028
    Репутация
    1489
    Цитата Сообщение от homo ludens Посмотреть сообщение
    код free(p); if(!p) ... абсолютно законен с точки зрения стандарта.
    незаконен код free(p); if(!*p)
    .
    а также незаконен код free (p); if (!p)
    Цитата Сообщение от homo ludens Посмотреть сообщение
    В стандарте С написано более просто.
    Any use of a pointer that refers to freed space results in undefined behavior.
    .
    и этим все сказано.
    все верно,
    могу даже найти пример платформы где подобный код неизбежно вызывает UB

  19. Вверх #19
    Постоялец форума Аватар для Guffy
    Пол
    Мужской
    Адрес
    Одесса
    Возраст
    49
    Сообщений
    1,356
    Репутация
    256
    если бы это было верно
    free (p);
    if (p==0) // здесь возникает UB
    это бы подразумевало, что free модифицирует содержимое переменной p (банально, как области памяти в 4 байта для 32битных систем).
    однако
    free(void* p) этого сделать не может.
    он должен быть либо free(void** p) либо free(void*& p) /а референсов в С, если не ошибаюсь, нет. между тем free - функция именно С-рунтайма, а не С++ /

  20. Вверх #20
    Постоялец форума Аватар для Guffy
    Пол
    Мужской
    Адрес
    Одесса
    Возраст
    49
    Сообщений
    1,356
    Репутация
    256
    Цитата Сообщение от Ull9 Посмотреть сообщение
    могу даже найти пример платформы где подобный код неизбежно вызывает UB
    ждемс


Ответить в теме
Страница 1 из 4 1 2 3 ... ПоследняяПоследняя

Социальные закладки

Социальные закладки

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения