Punter nul
En informàtica, un punter nul o una referència nul·la és un valor desat per indicar que el punter o referència no fa referència a un objecte vàlid. Els programes utilitzen habitualment punters nuls per representar condicions com ara el final d'una llista de longitud desconeguda o la fallada per realitzar alguna acció; aquest ús de punters nulls es pot comparar amb els tipus anul·lables i amb el valor Nothing d'un tipus d'opció.
Un punter nul no s'ha de confondre amb un punter no inicialitzat: es garanteix que un punter nul es compara desigual amb qualsevol punter que apunti a un objecte vàlid. Tanmateix, depenent de l'idioma i la implementació, és possible que un punter no inicialitzat no tingui cap garantia. Podria comparar-se igual a altres punters vàlids; o podria comparar-se igual a punters nuls. Pot fer les dues coses en diferents moments; o la comparació pot ser un comportament indefinit.
Com que un punter nul no apunta a un objecte significatiu, un intent d'accedir a les dades emmagatzemades en aquesta ubicació de memòria (no vàlida) pot provocar un error en temps d'execució o una fallada immediata del programa. Aquest és l'error del punter nul. És un dels tipus més comuns de debilitats del programari,[1] i Tony Hoare, que va introduir el concepte, s'ha referit a ell com un "error de mil milions de dòlars".
Llenguatge C
[modifica]A C, es garanteix que es comparen iguals dos punters nuls de qualsevol tipus. La macro del preprocessador NULL
es defineix com una constant de punter nul definida per la implementació a < stdlib.h >
, que en C99 es pot expressar de manera portàtil com ((void *)0)
, el que significa que el valor enter 0
es converteix al tipus void*
(punter a buit). L'estàndard C no diu que el punter nul sigui el mateix que el punter a l'adreça de memòria 0, tot i que això pot ser el cas a la pràctica. Desreferenciar un punter nul és un comportament indefinit en C, i una implementació conforme es permet assumir que qualsevol punter que es desreferencia no és nul.
A la pràctica, la desreferenciació d'un punter nul pot provocar un intent de lectura o escriptura des de la memòria que no està assignada, provocant un error de segmentació o una violació d'accés a la memòria. Això pot manifestar-se com una fallada del programa o transformar-se en una excepció de programari que es pot capturar pel codi del programa. Hi ha, però, certes circumstàncies en què no és així. Per exemple, en el mode real x86, l'adreça 0000:0000
és llegible i també es pot escriure, i desreferenciar un punter a aquesta adreça és una acció perfectament vàlida però normalment no desitjada que pot provocar un comportament indefinit però sense bloqueig a l'aplicació. Hi ha ocasions en què desreferenciar el punter a l'adreça zero és intencionat i està ben definit; per exemple, el codi de la BIOS escrit en C per a dispositius x86 en mode real de 16 bits pot escriure la taula de descriptors d'interrupció (IDT) a l'adreça física 0 de la màquina desreferenciant un punter nul per escriure. També és possible que el compilador optimitzi la desreferència del punter nul, evitant un error de segmentació però provocant un altre comportament no desitjat.[2]
Llenguatge C++
[modifica]En C++, mentre que la macro NULL
es va heretar de C, el literal enter de zero s'ha preferit tradicionalment per representar una constant de punter nul.[3] Tanmateix, C++11 va introduir la constant explícita de punter nul nullptr
i el tipus nullptr_t
que s'utilitzarà en el seu lloc.
Mitigació
[modifica]Hi ha tècniques per facilitar la depuració de referències de punter nul.[4] Bond et al.[4] suggereix modificar la màquina virtual Java (JVM) per fer un seguiment de la propagació nul·la.
Els llenguatges funcionals purs i el codi d'usuari que s'executen en molts llenguatges interpretats o de màquina virtual no pateixen el problema de la desreferenciació de punters nuls, ja que no es proporciona accés directe als punters i, en el cas dels llenguatges funcionals purs, tot el codi i les dades són immutables.
Referències
[modifica]- ↑ «CWE-476: NULL Pointer Dereference» (en anglès). MITRE.
- ↑ Lattner, Chris. «What Every C Programmer Should Know About Undefined Behavior #1/3» (en anglès). blog.llvm.org, 13-05-2011. Arxivat de l'original el 2023-06-14. [Consulta: 14 juny 2023].
- ↑ Stroustrup, Bjarne. «Chapter 5:
Theconst
qualifier (§5.4) prevents accidental redefinition ofNULL
and ensures thatNULL
can be used where a constant is required.». A: The C++ Programming Language (en anglès). 14th printing of 3rd. United States and Canada: Addison–Wesley, març 2001, p. 88. ISBN 0-201-88954-4. - ↑ 4,0 4,1 Bond, Michael D. «Tracking bad apples». A: Proceedings of the 22nd annual ACM SIGPLAN conference on Object oriented programming systems and applications - OOPSLA '07 (en anglès), 2007, p. 405. DOI 10.1145/1297027.1297057. ISBN 9781595937865.