Espressione: String iteratore non dereferencable
-
21-08-2019 - |
Domanda
Sto avendo un momento difficile utilizzando std :: string :: iteratori in C ++. Questo codice compila bene (ancora non ottenere corretta uscita, ma questo è colpa mia: TODO, fissare algoritmo) in Dev-C ++, e non ho ricevuto gli errori di runtime. L'errore è con Visual Studio Express 2008, C ++, dove sto ottenendo un errore che indica
Il mio debug mi dice che potrebbe tentare di dereference oltre la fine dell'input frase, ma non riesco a vedere dove. Qualcuno può fare luce?
std::string wordWrap(std::string sentence, int width)
{
std::string::iterator it = sentence.begin();
//remember how long next word is
int nextWordLength = 0;
int distanceFromWidth = width;
while (it < sentence.end())
{
while (*it != ' ' && it != sentence.end())
{
nextWordLength++;
distanceFromWidth--;
it++;
}
if (nextWordLength > distanceFromWidth)
{
*it = '\n';
distanceFromWidth = width;
nextWordLength = 0;
}
//skip the space
it++;
}
return sentence;
}
Soluzione
In primo luogo, l'operatore uso = () su iteratori, senza operatore <():
while (it != sentence.end())
In secondo luogo, questo è indietro: while (*it != ' ' && it != sentence.end())
fare qualcosa con l'iteratore, di verificare se l'iteratore è valido. Piuttosto, si dovrebbe verificare se è valida prima:
while (it != sentence.end() && *it != ' ')
In terzo luogo, è necessario utilizzare ++ iteratore su iteratore ++, anche se questo non è legato al vostro crash.
In quarto luogo, un problema principale è qui:
*it = '\n';
A causa del controllo precedente, while (it != sentence.end()
, è possibile raggiungere quel dereferenziare iteratore pur essendo alla fine. Una correzione potrebbe essere quella di fare questo:
if (it != sentence.end() && nextWordLength > distanceFromWidth)
Così ora se si è raggiunta la fine, ci si ferma.
Dopo aver fissato il numero precedente, ora l'unico problema è questo:
//skip the space
++it;
Questo presuppone che il carattere si sta saltando è in realtà uno spazio. Ma per quanto riguarda la fine della stringa? Eseguire questa funzione con questa stringa:
"a test string " // <- space at end
E avrà successo; salta lo spazio, mettendo l'iteratore in end()
, il ciclo si interrompe e il successo.
Tuttavia, senza lo spazio che andrà in crash, perché avete raggiunto la fine, e stanno per saltare oltre la fine. Per risolvere il problema, aggiungere un controllo:
//skip the space
if (it != sentence.end())
{
++it;
}
Con conseguente questo codice finale:
std::string wordWrap(std::string sentence, int width)
{
std::string::iterator it = sentence.begin();
//remember how long next word is
int nextWordLength = 0;
int distanceFromWidth = width;
while (it != sentence.end())
{
while (it != sentence.end() && *it != ' ')
{
nextWordLength++;
distanceFromWidth--;
++it;
}
if (it != sentence.end() && nextWordLength > distanceFromWidth)
{
*it = '\n';
distanceFromWidth = width;
nextWordLength = 0;
}
//skip the space
if (it != sentence.end())
{
++it;
}
}
return sentence;
}
Si potrebbe notare Questo sembra che ha un sacco di controlli ridondanti. Questo può essere risolto:
std::string wordWrap(std::string sentence, int width)
{
std::string::iterator it = sentence.begin();
//remember how long next word is
int nextWordLength = 0;
int distanceFromWidth = width;
while (it != sentence.end())
{
while (*it != ' ')
{
nextWordLength++;
distanceFromWidth--;
++it;
// check if done
if (it == sentence.end())
{
return sentence;
}
}
if (nextWordLength > distanceFromWidth)
{
*it = '\n';
distanceFromWidth = width;
nextWordLength = 0;
}
//skip the space
++it;
}
return sentence;
}
Si spera che aiuta!
Altri suggerimenti
while (*it != ' ' && it != sentence.end())
modifiche
while (it != sentence.end() && *it != ' ')
così la seconda espressione non viene valutata se il primo se falso.
if (nextWordLength > distanceFromWidth)
dovrebbe probabilmente passare alla
if (it == sentence.end())
break;
if (nextWordLength > distanceFromWidth)
Quasi certamente l'errore è il risultato di:
*it = '\n';
Dal momento che nel precedente ciclo while una delle tue condizioni di arresto è:
it != sentence.end()
Se == sentence.end (), allora * è = '\ n' non volerà
Non ci sono più errori, ma questo è quello che sta causando i problemi presenti.