Off-by-one error: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
- S |
m Prosa Etichette: Modifica visuale Modifica da mobile Modifica da web per mobile Modifica da mobile avanzata |
||
(16 versioni intermedie di 10 utenti non mostrate) | |||
Riga 1:
Un
▲Un errore '''off-by-one error''' ('''OBOE'''), detto anche '''OBOB''' ('''off-by-one bug'''), è un errore logico di [[Programmazione (informatica)|programmazione]] che avviene quando un [[Iterazione|ciclo iterativo]] viene ripetuto una volta di troppo o una volta di meno, a causa di un errore nella specifica della condizione di verità: solitamente accade quando il programmatore mette erroneamente il simbolo di ''minore o uguale'' al posto del simbolo ''minore'', o il simbolo ''maggiore o uguale'' al posto di ''maggiore'', oppure quando commette un errore nell'inizializzazione della [[variabile (informatica)|variabile]] testata, settandola a zero anziché a uno: questo causa problemi ad esempio se essa si riferisce all'indice di un [[array]] (il quale in molti linguaggi di programmazione comincia da zero); oppure nel caso in cui essa poi sia usata in una divisione (nel qual caso è bene sia settata a valori diversi da zero, per evitare eccezioni del tipo ''divisione per zero'').
== Iterazioni oltre il termine dell'
Consideriamo un [[array]] di oggetti, dei quali
Proprio per via di questa contro-intuitività, i range nell'informatica sono spesso rappresentati da [[Intervallo (matematica)|intervalli]] semi-aperti; il range da ''m'' ad ''n'' inclusivo infatti, è rappresentato dagli elementi che vanno da ''m'' (incluso)
for (i = 0; i < 5; i++)
{
Line 18 ⟶ 17:
Errori relativi agli array possono inoltre essere risultato di differenze concettuali tra i vari linguaggi di programmazione. La numerazione che fa riferimento alla prima cella come la cella 0 è molto comune, ma alcuni linguaggi la numerano come la 1. [[Pascal (linguaggio di programmazione)|Pascal]] utilizza gli array con indici definiti dagli utenti, rendendone possibile la modellazione successivamente al problema del dominio.
== Errore
[[File:Fencepost error 01.svg|miniatura|upright=1.2|Una recinzione dritta con ''n'' sezioni ha {{Nowrap|''n'' + 1}} paletti]]
Un '''errore fencepost''' (letteralmente "
In araeostylis enim libertas est quantum cuique libet
constituendi. Sed ita columnae in peripteris conlocentur uti quot
intercolumnia sunt in fronte, totidem bis intercolumnia fiant in
lateribus. Ita enim erit duplex longitudo operis ad
latitudinem. Namque qui columnarum duplicationes fecerunt erravisse
videntur, quod unum intercolumnium in longitudine plus quam oportet
procurrere videtur.|accesso=2017-11-04|urlarchivio=https://web.archive.org/web/20171107003005/http://www.dsm.fordham.edu/~moniot/Opinions/fencepost-error-history.shtml|dataarchivio=7 novembre 2017|urlmorto=sì}}</ref> Il problema si può illustrare nel modo seguente:
{{Quote|Se costruisci una recinzione dritta lunga 30 metri, con paletti spaziati 3 metri l'uno dall'altro, di quanti paletti necessiti?}}
Line 34 ⟶ 41:
La risposta corretta dovrebbe essere ''n'' – 1 se la sequenza di paletti è aperta alla fine, ''n'' se si chiudono a cerchio, o ''n'' + 1 se il lato aperto della sequenza di paletti è considerato come una sezione. Bisogna prestare molta attenzione alla definizione precisa del problema, perché il setup di una certa configurazione potrebbe dare la risposta sbagliata per altre. Errori di fencepost derivano in sostanza dal contare gli elementi piuttosto che gli spazi che li separano e viceversa, o trascurando di considerare se l’oggetto in esame dovrebbe essere contato soltanto in uno o in entrambi gli estremi della fila.
Errori di fencepost possono inoltre verificarsi in [[unità di misura]] diverse dalle lunghezze. Ad esempio, la “Time Pyramid” è una costruzione costituita da 120 blocchi da piazzarsi a distanza di 10 anni l’uno dall’altro. Saranno quindi necessari 1190 anni per la costruzione completa, dal piazzamento del primo blocco sino all’ultimo, e non 1200. Uno dei primi errori di tipo fencepost vide coinvolta l’unità di misura temporale, nel caso specifico del [[Calendario giuliano|calendario Giuliano]]. Esso originariamente calcolava gli [[Calendario giuliano#Anni bisestili|anni bisestili]] in maniera errata, considerandoli in maniera inclusiva invece che esclusiva, originandone quindi uno ogni 3 anni invece che quattro.
Un errore di fencepost può, in rari casi, essere collegato ad un errore introdotto da regolarità inaspettate in valori di input, che possono (per esempio) contrastare completamente con un’implementazione teoricamente efficiente di [[Albero binario|alberi binari]] o [[Funzione di hash|funzioni di hash]]. Questo errore può implicare il verificarsi dei casi peggiori di un [[algoritmo]], invece che quelli attesi.
Line 50 ⟶ 57:
strncat(buf, s, sizeof(buf)); //Il parametro finale dovrebbe essere: sizeof(buf) - 1
}
</syntaxhighlight>Errori di tipo off-by-one sono comuni nell'utilizzo delle librerie C, perché non coerenti tra loro in situazioni nelle quali, come nell’esempio, ci si deve ricordare di sottrarre un byte: funzioni come <code>fgets()</code> e <code>strncpy</code> non scriveranno mai oltre la lunghezza della stringa a loro indicata (<code>fgets()</code> sottrae 1 e restituisce soltanto (
In alcuni sistemi (in particolare architetture di tipo [[Ordine dei byte|little endian]]) questa incoerenza può causare una sovrascrittura dell’ultimo byte significativo del frame pointer. Si crea così una condizione sfruttabile per un aggressore, che può dirottare le variabile locale per la routine di chiamata.
Un approccio utile per cercare di prevenire alcuni problemi è usare varianti di queste funzioni, che calcolino quanto scrivere basandosi sulla lunghezza totale del buffer, piuttosto che sul massimo numero di caratteri da scrivere. Queste possono essere funzioni come la <code>strlcat</code> e <code>strlcpy</code>, spesso considerate più sicure perché rendono più facile prevenire scritture accidentali oltre la fine del buffer (nell'esempio di codice riportato sopra, chiamare <code>strlcat(buf, s, sizeof(buf))</code> risolverebbe il problema)
== Note ==▼
<references />▼
== Voci correlate ==
*
* [[Asserzione (informatica)
* [[Ciclo for]]
* [[Sicurezza informatica]]
== Collegamenti esterni ==
* {{Cita web|url=http://foldoc.org/fencepost_error|titolo=Fencepost error}}
* {{Cita web|autore=Edsger Wybe Dijkstra
{{Portale|informatica}}
[[Categoria:Terminologia informatica]]
[[Categoria:Sicurezza informatica]]
▲== Note ==
▲<references />
▲* Edsger Wybe Dijkstra (2 Maggio 2008). [http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html "Why numbering should start at zero (EWD 831)"]. Archivi ''E. W. Dijkstra''. [[Università del Texas a Austin|Università di Austin in Texas]]. Informazioni recuperate il 3 Marzo 2011.
|