Stringa null-terminata: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Creata dalla traduzione della pagina "Null-terminated string"
 
sistemate le note
Riga 1:
 
In [[Programmazione (informatica)|programmazione]], una '''stringa null-terminata''' è una [[Stringa (informatica)|stringa di caratteri]] memorizzata come un [[Array|vettore]] contenente i caratteri e terminata con un carattere null (un carattere con valore zero, chiamato NUL in questo articolo). I nomi alternativi sono '''stringa C''', che si riferisce al [[C (linguaggio)|linguaggio di programmazione C]] e '''ASCIIZ''' (sebbene C possa usare codifiche diverse da ASCII).
 
Line 7 ⟶ 6:
Le stringhe null-terminate sono state introdotte dalla direttiva <code>.</code> <code>ASCIZ</code> dei [[Linguaggio assembly|linguaggi assembly]] [[PDP-11]] e dalla direttiva <code>ASCIZ</code> del linguaggio assembly macro MACRO-10 per il [[PDP-10]]. Questi precedono lo sviluppo del linguaggio di programmazione C, ma sono state spesso utilizzate altre forme di stringhe.
 
Al momento dello sviluppo del C (e dei linguaggi da cui deriva), la memoria era estremamente limitata, quindi l'utilizzo di un solo byte di sovraccarico per memorizzare la lunghezza di una stringa era interessante. L'unica alternativa popolare a quel tempo, solitamente chiamata "stringa Pascal" (un termine più moderno è "[[Stringa (informatica)|lunghezza prefissata]]"), utilizzava un ''byte iniziale'' per memorizzare la lunghezza della stringa. Ciò consente alla stringa di contenere NUL e la ricerca della lunghezza di una stringa già memorizzata richiede solo un accesso alla memoria in [[Complessità temporale|tempo costante]] O(1), ma la lunghezza della stringa è limitata a 255 caratteri (su una macchina che utilizza byte a 8 bit). Il progettista del linguaggio C [[Dennis Ritchie]] ha scelto di seguire la convenzione della terminazione con carattere nullo per evitare la limitazione della lunghezza di una stringa e perché mantenere il conteggio sembrava, nella sua esperienza, meno conveniente rispetto all'utilizzo di un terminatore.<ref>{{Cita conferenza|titolo=The development of the C language|conferenza=Second History of Programming Languages conference|autore=Dennis M. Ritchie|data=Aprile 1993|città=Cambridge (MA)|wkautore=Dennis Ritchie|url=https://www.bell-labs.com/usr/dmr/www/chist.html|lingua=EN}}</ref> <ref>{{Cita libro|autore=Ritchie|nome=Dennis M.|cognome=Ritchie|wkautore=Dennis Ritchie|curatore=Thomas J. Bergin, Jr. , Richard G. Gibson, Jr.|altri=Addison-Wesley (Reading, Mass)|titolo=History of Programming Languages|ed=2|anno=1996|editore=ACM Press|città=New York|lingua=EN|capitolo=The development of the C language|ISBN=0-201-89502-1}}</ref>
 
Ciò ha avuto una certa influenza sulla progettazione del [[Instruction set|set di istruzioni]] della CPU. Alcune CPU negli anni '70 e '80, come [[Zilog Z80]] e [[Digital Equipment Corporation|DEC]] [[Virtual Address eXtension|VAX]], avevano istruzioni dedicate per la gestione delle stringhe con prefisso di lunghezza. Tuttavia, quando la stringhe null-terminate hanno guadagnato trazione, i progettisti delle CPU hanno iniziato a tenerne conto, come si è visto ad esempio nella decisione di IBM di aggiungere le istruzioni "Logical String Assist" all'ES/9000 520 nel 1992.
 
Lo sviluppatore [[FreeBSD]] [[Poul-Henning Kamp]], scrivendo in ''ACM Queue'', ha definito la vittoria delle stringhe null-terminate su una lunghezza di 2 byte (non un byte) come "l'errore di un byte più costoso" di sempre.<ref>{{Cita testo|lingua=EN|autore=Poul-Henning Kamp|titolo=The Most Expensive One-byte Mistake|pubblicazione=ACM Queue|data=25 luglio 2011|url=http://queue.acm.org/detail.cfm?id=2010365|vol=9|numero=7|accesso=2 agosto 2011|issn=1542-7730}}</ref>
 
== Limitazioni ==
Sebbene semplice da implementare, questa rappresentazione è stata soggetta a errori e problemi di prestazione.
 
La terminazione nulla ha storicamente creato [[Sicurezza informatica|problemi di sicurezza]].<ref>{{Cita pubblicazione|autore=Rain Forest Puppy|data=9 Septembersettembre 1999|titolo=Perl CGI problems|rivista=Phrack Magazine|editore=artofhacking.com|volume=9|numero=55|p=7|accesso=3 Januarygennaio 2016|url=http://insecure.org/news/P55-07.txt}}</ref> Un NUL inserito nel mezzo di una stringa la troncherà inaspettatamente.<ref>{{Cita web|url=https://security.stackexchange.com/questions/48187/null-byte-injection-on-php|titolo=Null byte injection on PHP?|sito=Information Security Stack Exchange|accesso=2021-07-01}}</ref> Un bug comune era quello di non allocare lo spazio aggiuntivo per il NUL, che quindi veniva scritto sulla memoria adiacente. Un altro era di non scrivere affatto il NUL, che spesso non veniva rilevato durante il test perché il blocco di memoria conteneva già degli zeri. A causa delle spese per trovare la lunghezza, molti programmi non si sono preoccupati di copiare una stringa in un [[buffer]] di dimensioni fisse, causando un [[Buffer overflow|overflow del buffer]] se era troppo lungo.
 
L'impossibilità di memorizzare uno zero richiede che testo e dati binari siano mantenuti distinti e gestiti da funzioni diverse (quest'ultima richiede che venga fornita anche la lunghezza dei dati). Ciò può portare a ridondanza del codice ed errori quando viene utilizzata la funzione sbagliata.
Line 23 ⟶ 22:
 
== Codifiche dei caratteri ==
Le stringhe null-terminate richiedono che la codifica non utilizzi un byte zero (0x00) da nessuna parte, quindi non è possibile memorizzare tutte le possibili [[ASCII|stringhe ASCII]] o [[UTF-8]].<ref>{{Cita web|url=http://tools.ietf.org/html/rfc3629#section-3|titolo=UTF-8, a transformation format of ISO 10646|dataaccesso=19 Septembersettembre 2013}}</ref><ref><!-- This is the encoding table provided as a resource by the Unicode consortium: http://www.unicode.org/resources/utf8.html -->{{Cita web|url=http://www.utf8-chartable.de/|titolo=Unicode/UTF-8-character table|dataaccesso=13 Septembersettembre 2013}}</ref><ref>{{Cita web|url=http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8|titolo=UTF-8 and Unicode FAQ|cognome=Kuhn|nome=Markus|dataaccesso=13 Septembersettembre 2013}}</ref> Tuttavia, è comune memorizzare il sottoinsieme di ASCII o UTF-8 – ogni carattere tranne NUL – in stringhe null-terminate. Alcuni sistemi usano "[[UTF-8|UTF-8 modificato]]" che codifica NUL come due byte diversi da zero (0xC0, 0x80) e quindi consente di memorizzare tutte le stringhe possibili. Questo non è consentito dallo standard UTF-8, perché è una [[UTF-8|codifica troppo lunga]] ed è vista come un rischio per la sicurezza. Alcuni altri byte possono essere invece utilizzati come fine della stringa, come 0xFE o 0xFF, che non vengono utilizzati in UTF-8.
 
[[UTF-16]] utilizza numeri interi a 2 byte e poiché entrambi i byte possono essere zero (e infatti ''ogni altro'' byte lo è, quando si rappresenta testo ASCII), non può essere archiviato in una stringa di byte con terminazione null. Tuttavia, alcuni linguaggi implementano una stringa di caratteri [[UTF-16]] a 16 bit, terminata da un NUL a 16 bit.
Line 30 ⟶ 29:
Sono stati fatti molti tentativi per rendere la gestione delle stringhe C meno soggetta a errori. Una strategia consiste nell'aggiungere funzioni più sicure come <code>strdup</code> e <code>strlcpy</code>, [[Libreria standard del C|deprecando al contempo l'uso di funzioni non sicure]] come <code>gets</code>. Un altro è aggiungere un wrapper orientato agli oggetti attorno alle stringhe C in modo che possano essere eseguite solo chiamate sicure. Tuttavia anche così facendo risulta comunque possibile chiamare le funzioni non sicure.
 
La maggior parte delle librerie moderne sostituisce le stringhe C con una struttura contenente un valore di lunghezza pari o superiore a 32 bit (molto più di quanto non sia mai stato considerato per le stringhe di lunghezza prefissata) e spesso aggiunge un altro puntatore, un conteggio dei riferimenti e persino un NUL per accelerare la retroconversioneconversione inversa ad una stringa C. La memoria ora è molto più grande, in modo tale che se l'aggiunta di 3 (o 16 o più) byte a ciascuna stringa è un problema reale, il software dovrà gestire così tante piccole stringhe che qualche altro metodo di archiviazione farà risparmiare ancora più memoria (ad esempio potrebbero esserci così tanti duplicati che una [[Hash table|tabella hash]] utilizzerà meno memoria). Gli esempi includono la [[Standard Template Library]] del [[C++]]<code>[[Stringa (C++)|std::string]]</code>, [[Qt (toolkit)|Qt]] <code>QString</code>, [[Microsoft Foundation Classes|MFC]] <code>CString</code> e l'implementazione basata sul inguaggiolinguaggio C <code>CFString</code> di [[Core Foundation]], nonché il fratello [[Objective-C]] <code>NSString</code> di Foundation, entrambi di Apple. Strutture più complesse possono essere utilizzate anche per riporre le stringhe come le [[Corde (informatica)|corde]].
 
== Vedi anche ==
 
== Voci correlate ==
* [[Stringa vuota]]
* [[Valore sentinella]]
 
== Note ==
<references />
 
{{Portale|informatica}}
== Bibliografia ==
[[Categoria:Stringhe]]