NULL у мовах програмування Сі і — макрос, оголошений у заголовному файлі stddef.h (та інших заголовних файлах). Значенням цього макроса є залежна від реалізації константа нульового вказівника (англ. null pointer constant).
Константа нульового вказівника — це цілочисельний константний вираз зі значенням 0 або (тільки в Сі) такий самий вираз, але зведений до типу void*
. Константа нульового вказівника, зведена до будь-якого типу вказівників, є нульовим вказівником. Гарантується, що нульовий вказівник не дорівнює вказівнику на будь-який об'єкт (в широкому сенсі слова, будь-які дані) або функцію. Гарантується, що будь-які два нульових вказівники рівні між собою. Розіменування нульового вказівника є операцією з невизначеною поведінкою.
Інакше кажучи, реалізація надає спеціальне значення — константу нульового вказівника, яку можна присвоїти будь-якому вказівнику і такий вказівник під час порівняння не дорівнюватиме будь-якому «правильному» вказівнику. Тобто, можна вважати, що нульовий вказівник не містить правильної адреси в пам'яті.
Використання
Нульові вказівники придумані як зручний спосіб «позначити» вказівники, які не вказують на правильну адресу в пам'яті. Наприклад, під час оголошення вказівника як автоматичної змінної його значення не визначене. Щоб позначити, що цей вказівник ще не містить правильної адреси в пам'яті, такому вказівнику присвоюють константу нульового вказівника:
void f(void) { int *x = NULL; /* ... */ }
Хорошим стилем програмування є присвоювання вказівнику після вивільнення пам'яті, на яку він посилався, нульового вказівника. Крім цього, застосування обнулення вказівників актуальне для безпеки вивільнення пам'яті: операція в C++ ( в Сі) безпечна для нульового вказівника. Наприклад:
TYPE *foo = new TYPE(); // використання foo delete foo;// foo != NULL // якийсь код програми delete foo;// ПОМИЛКА! Память вже недоступна
тоді як у такому варіанті помилки не буде
TYPE *foo = new TYPE(); // використання foo delete foo;// foo != NULL foo = NULL;// foo == NULL // якийсь код програми delete foo;// помилки немає: delete перевіряє значення foo
Розмірність вказівника
Під час виклику функції в один з аргументів можна передати NULL. Макрос NULL у різних компіляторах можна визначити різними способами, зокрема
#define NULL 0
#define NULL ((void *)0)
У першому випадку NULL має тип int, а в другому — тип void*. Існують архітектури, де sizeof (int) != sizeof (void*), тоді на різних платформах до функції надходитиме різна кількість байтів, що може порушити її роботу. Нині робиться спроба вирішити цю проблему в Сі введенням nullptr, див. пропозицію N 2394.
Розіменовування нульових вказівників
Розіменування нульового вказівника є операцією з невизначеною поведінкою. На реалізацію не накладається жодних обмежень: може статися, наприклад, звернення до пам'яті, не призначеної для використання даною програмою (тобто при читанні буде прочитано «сміття», а при записі — значення потрапить в ділянку пам'яті, що не належить програмі). Наприклад, у DOS запис за нульовою адресою затре принаймні нульовий вектор переривань, так що наступний виклик int 0 призведе, найпевніш, до зависання системи. Однак найчастіше це призводить до часу виконання (якщо в операційній системі реалізовано захист пам'яті і доступ до невиділеної процесу пам'яті блокується). Наприклад, у Windows 9x повідомлення «Загальна помилка захисту» — «Програма виконала неприпустиму операцію і буде закрита» (англ. general protection fault, GPF) виводиться найчастіше в тих випадках, коли програма звертається до пам'яті за некоректним (зокрема й неініціалізованим або вже звільненим) вказівником. В UNIX-подібних операційних системах у таких ситуаціях процес отримує сигнал SIGSEGV і його опрацьовувач виводить повідомлення «Segmentation fault».
Нульові вказівники в C++
Якщо брати конкретну реалізацію NULL за сирцевими файлами, то він може бути визначеним як (void*)0 або як 0. Використання NULL у проектах мовою C++ може призводити до помилок. Наприклад
int (ClassName::*pf)() = NULL;
призведе до помилки компіляції в разі, якщо NULL визначено як (void*)0 (наприклад опосередковано включено заголовок, де стандартне для C++ визначення NULL перекривається). Тому в програмах на C++ не рекомендується використовувати NULL у вигляді ((void*) 0). У стандарті для позначення нульового вказівника додано нове ключове слово nullptr.
Див. також
Примітки
- N 2394 (PDF). Open Standards (English) . (PDF) оригіналу за 27 липня 2020. Процитовано 22 травня 2020.
- JTC1/SC22/WG21 — The C++ Standards Committee (2 жовтня 2007). SC22/WG21/N2431 = J16/07-0301 «A name for the null pointer: nullptr» (PDF). JTC1.22.32 (англ.). . Архів оригіналу (PDF) за 11 лютого 2012. Процитовано 4 жовтня 2010.(англ.)
Посилання
- Question 5.1. c-faq.com. Архів оригіналу за 26 лютого 2013. Процитовано 2 квітня 2022.
- . c-faq.com. Архів оригіналу за 18 серпня 2011. Процитовано 2 квітня 2022.
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
NULL u movah programuvannya Si i C makros ogoloshenij u zagolovnomu fajli stddef h ta inshih zagolovnih fajlah Znachennyam cogo makrosa ye zalezhna vid realizaciyi konstanta nulovogo vkazivnika angl null pointer constant Konstanta nulovogo vkazivnika ce cilochiselnij konstantnij viraz zi znachennyam 0 abo tilki v Si takij samij viraz ale zvedenij do tipu void Konstanta nulovogo vkazivnika zvedena do bud yakogo tipu vkazivnikiv ye nulovim vkazivnikom Garantuyetsya sho nulovij vkazivnik ne dorivnyuye vkazivniku na bud yakij ob yekt v shirokomu sensi slova bud yaki dani abo funkciyu Garantuyetsya sho bud yaki dva nulovih vkazivniki rivni mizh soboyu Rozimenuvannya nulovogo vkazivnika ye operaciyeyu z neviznachenoyu povedinkoyu Inakshe kazhuchi realizaciya nadaye specialne znachennya konstantu nulovogo vkazivnika yaku mozhna prisvoyiti bud yakomu vkazivniku i takij vkazivnik pid chas porivnyannya ne dorivnyuvatime bud yakomu pravilnomu vkazivniku Tobto mozhna vvazhati sho nulovij vkazivnik ne mistit pravilnoyi adresi v pam yati VikoristannyaNulovi vkazivniki pridumani yak zruchnij sposib poznachiti vkazivniki yaki ne vkazuyut na pravilnu adresu v pam yati Napriklad pid chas ogoloshennya vkazivnika yak avtomatichnoyi zminnoyi jogo znachennya ne viznachene Shob poznachiti sho cej vkazivnik she ne mistit pravilnoyi adresi v pam yati takomu vkazivniku prisvoyuyut konstantu nulovogo vkazivnika void f void int x NULL Horoshim stilem programuvannya ye prisvoyuvannya vkazivniku pislya vivilnennya pam yati na yaku vin posilavsya nulovogo vkazivnika Krim cogo zastosuvannya obnulennya vkazivnikiv aktualne dlya bezpeki vivilnennya pam yati operaciya delete v C v Si bezpechna dlya nulovogo vkazivnika Napriklad TYPE foo new TYPE vikoristannya foo delete foo foo NULL yakijs kod programi delete foo POMILKA Pamyat vzhe nedostupna todi yak u takomu varianti pomilki ne budeTYPE foo new TYPE vikoristannya foo delete foo foo NULL foo NULL foo NULL yakijs kod programi delete foo pomilki nemaye delete pereviryaye znachennya fooRozmirnist vkazivnikaPid chas vikliku funkciyi v odin z argumentiv mozhna peredati NULL Makros NULL u riznih kompilyatorah mozhna viznachiti riznimi sposobami zokrema define NULL 0 define NULL void 0 U pershomu vipadku NULL maye tip int a v drugomu tip void Isnuyut arhitekturi de sizeof int sizeof void todi na riznih platformah do funkciyi nadhoditime rizna kilkist bajtiv sho mozhe porushiti yiyi robotu Nini robitsya sproba virishiti cyu problemu v Si vvedennyam nullptr div propoziciyu N 2394 Rozimenovuvannya nulovih vkazivnikivRozimenuvannya nulovogo vkazivnika ye operaciyeyu z neviznachenoyu povedinkoyu Na realizaciyu ne nakladayetsya zhodnih obmezhen mozhe statisya napriklad zvernennya do pam yati ne priznachenoyi dlya vikoristannya danoyu programoyu tobto pri chitanni bude prochitano smittya a pri zapisi znachennya potrapit v dilyanku pam yati sho ne nalezhit programi Napriklad u DOS zapis za nulovoyu adresoyu zatre prinajmni nulovij vektor pererivan tak sho nastupnij viklik int 0 prizvede najpevnish do zavisannya sistemi Odnak najchastishe ce prizvodit do chasu vikonannya yaksho v operacijnij sistemi realizovano zahist pam yati i dostup do nevidilenoyi procesu pam yati blokuyetsya Napriklad u Windows 9x povidomlennya Zagalna pomilka zahistu Programa vikonala nepripustimu operaciyu i bude zakrita angl general protection fault GPF vivoditsya najchastishe v tih vipadkah koli programa zvertayetsya do pam yati za nekorektnim zokrema j neinicializovanim abo vzhe zvilnenim vkazivnikom V UNIX podibnih operacijnih sistemah u takih situaciyah proces otrimuye signal SIGSEGV i jogo opracovuvach vivodit povidomlennya Segmentation fault Nulovi vkazivniki v C Yaksho brati konkretnu realizaciyu NULL za sircevimi fajlami to vin mozhe buti viznachenim yak void 0 abo yak 0 Vikoristannya NULL u proektah movoyu C mozhe prizvoditi do pomilok Naprikladint ClassName pf NULL prizvede do pomilki kompilyaciyi v razi yaksho NULL viznacheno yak void 0 napriklad oposeredkovano vklyucheno zagolovok de standartne dlya C viznachennya NULL perekrivayetsya Tomu v programah na C ne rekomenduyetsya vikoristovuvati NULL u viglyadi void 0 U standarti C 11 dlya poznachennya nulovogo vkazivnika dodano nove klyuchove slovo nullptr Div takozhPomilka segmentaciyi Variativna funkciyaPrimitkiN 2394 PDF Open Standards English PDF originalu za 27 lipnya 2020 Procitovano 22 travnya 2020 JTC1 SC22 WG21 The C Standards Committee 2 zhovtnya 2007 SC22 WG21 N2431 J16 07 0301 A name for the null pointer nullptr PDF JTC1 22 32 angl Arhiv originalu PDF za 11 lyutogo 2012 Procitovano 4 zhovtnya 2010 angl PosilannyaQuestion 5 1 c faq com Arhiv originalu za 26 lyutogo 2013 Procitovano 2 kvitnya 2022 c faq com Arhiv originalu za 18 serpnya 2011 Procitovano 2 kvitnya 2022