2012-01-19 8 views
6

Non sono sicuro di cosa c'è di sbagliato con questo codice:Perché la chiamata a std :: vector :: back() in crash il mio programma

std::vector<int> myVector(0); 

if (myVector.back() == 12) 
    myVector.push_back(12); 

Sembra che richiamare() su un vettore vuoto si blocca il programma.

Non capisco perché si blocca? Dobbiamo controllare la lunghezza del vettore prima di chiamare back()? o è possibile che si tratti di un bug?

La documentazione dice che se il vettore è vuoto restituisce un valore non definito.

+1

Sospetto che importi qualcuno che ti dà -1 per l'utilizzo di MSDN come riferimento invece dello standard C++. Gli implementatori sono autorizzati a definire ulteriormente cosa fa la loro implementazione nei casi in cui lo standard dice UB, quindi se MS vuole garantire che 'back()' ritornerà quando usato su un vettore vuoto, hanno il diritto di farlo. Se stai usando MSVC++ hai diritto a leggere la loro documentazione. Ma potrebbe invece essere -1 per non rendersi conto che l'utilizzo di un "valore non definito" in qualsiasi modo, può causare un arresto anomalo. –

+0

@SteveJessop Penso che MSDN sia l'implementazione dello standard C++. Ma è strano che chiamare un metodo su un elemento valido (per quanto io sappia che un vettore vuoto è un elemento valido) causa il crash del mio programma. Bene, se lo standard dice così, così sia :) – MBen

+1

MSVC++ è * un * implementazione di (circa) lo standard C++. Altre implementazioni si comportano diversamente, se lo standard non indica il comportamento. Il motivo per cui lo standard non definisce la chiamata di 'back()' su un vettore vuoto è che le implementazioni non hanno bisogno di codice di caso speciale per questo. Possono quindi scegliere di essere più veloci di quanto sarebbero se dovessero controllare se il vettore fosse vuoto o meno, e fare cose diverse in casi diversi. Saranno inclini a schiantarsi (o peggio) quando farai qualcosa di sbagliato. Può sembrare strano, ma è un compromesso fatto come parte del design della lingua. –

risposta

13

dobbiamo controllare la lunghezza del vettore prima di richiamare()?

In una parola: sì. Questo è il tuo bug, il tuo vettore è vuoto quindi non c'è alcun elemento "indietro".

La documentazione dovrebbe dire (se si dice qualcosa a tutti) che chiamare back() su un vettore vuoto provoca comportamento indefinito, non che restituisce un valore indefinito.

+0

Per qualche motivo, MSDN dice "il valore restituito non è definito" (http://msdn.microsoft.com/en-us/library/0532x4xk%28v=vs.80%29.aspx). Ma dice anche, "Durante la compilazione con _SECURE_SCL 1, si verificherà un errore di runtime se si tenta di accedere a un elemento in un vettore vuoto". Non so (a) perché la MS si riferisca a un riferimento come un "valore", o (b) come quadrano la nozione di un "valore non definito" con la nozione di un riferimento che si traduce in un errore di runtime quando usato . Ma quell'errore di runtime potrebbe essere la stessa cosa che l'interrogante descrive come "crash". –

+0

Continuo a pensare che sia strano che chiamare un metodo su un elemento valido blocchi il mio programma. – MBen

+0

@MBen: Ma non ci sono elementi nel tuo vettore; è una precondizione di 'back()' che ci sia almeno un elemento nel tuo vettore. Questo è il modo in cui viene definita l'interfaccia. È necessario assicurarsi che il proprio input sia conforme alla condizione preliminare prima di tentare di chiamare 'back()'. –

5

C++ 11 di serie racconta questo:

23.3.2.8/3

L'e ff etto di chiamare anteriore() o posteriore() per un array di dimensioni zero è fi nita unde.

Poiché il comportamento non è definito, può succedere di tutto. Sei stato fortunato ad avere un incidente.

+0

Non penso di essere fortunato, mi sembra strano che chiamare un metodo su un valore valido valore si blocca il mio programma. – MBen

+3

@MBen Avere un crash del programma su UB è buono, perché è facile rilevare l'errore. Quando a volte funziona e talvolta no, è molto difficile trovare il bug. –

+0

Sono d'accordo. Ho solo bisogno di assicurarmi che il vettore abbia elementi :-) – MBen