8

Tutti gli esempi che sono stato in grado di trovare online sull'incremento di un puntatore che causa un segfault implicano la dereferenziazione del puntatore - cosa succede se voglio solo incrementarlo (ad esempio alla fine di un ciclo for) e io Non importa se finisce nella memoria non valida perché non la userò più. Ad esempio, in questo programma ho solo bisogno di passare da 4 ogni iterazione, ma non rinuncio mai più a questi puntatori dopo l'ultima iterazione.È possibile incrementare un puntatore senza dereferenziamento ancora segfault o avere altre cattive intenzioni (non definite)?

float* leftRowPointer, resultRowPointer; 
// assume they were correctly initialized 

for (unsigned int i = 0; i < 4; ++i, leftRowPointer += 4, resultRowPointer += 4) { 
    // do some stuff 
} 

Ho invece bisogno di fare qualcosa del genere?

for (unsigned int i = 0; i < 4; ++i) { 
    // same stuff 
    if (i != 3) { 
     leftRowPointer += 4; 
     resultRowPointer += 4; 
    } 
} 

C'è un modo migliore per realizzare ciò che sto cercando di fare?

Quando l'ho provato personalmente non sembra succedere niente di male, ma non è certo una garanzia che funzionerà sempre, e sfortunatamente non ho accesso a Valgrind o simili al lavoro.

Stiamo usando lo standard C++ 11, FWIW, e non ho trovato nulla che si applichi direttamente a questo, ma sarò il primo ad ammettere che non conosco bene lo standard abbastanza per avere una buona idea di dove cercarlo.

+1

Cerca in Operatori additivi (probabilmente [expr.plus] o qualcosa come §5.5). – chris

+0

Quali sono i tipi di 'leftRowPointer' e' resultRowPointer'? In generale, i puntatori incrementali sono sicuri. Se, tuttavia, si tratta di un tipo personalizzato con operatore 'sovrascritto + =', allora sarà necessario verificare la sicurezza della funzione personalizzata. – inetknght

+1

Questo potrebbe essere utile per rispondere alla tua domanda: http://stackoverflow.com/questions/2728299/why-is-comparing-against-end-iterator-legal –

risposta

8

Sezione 5.7, "Operatori additivi", il paragrafo 5 lo specifica - il risultato dell'aggiunta stessa non è definito; il programma non è valido anche se non si inviano mai i puntatori.

Se sia il puntatore operando e il punto risultato a elementi dello stesso oggetto array , o uno dopo l'ultimo elemento dell'array dell'oggetto, la valutazione non deve produrre un overflow; in caso contrario, il comportamento non è definito.

È altamente improbabile che segfault anche se è consentito, ma è ancora indefinito con tutto ciò che comporta.

4

Se solo l'assegnazione di un riferimento non valido a un puntatore era un problema, l'inizializzazione di uno su NULL sarebbe anche un problema. Quindi la risposta alla tua domanda specifica è "no".

+1

Credo, in realtà c'è una differenza tra il puntatore non valido e null. E credo che ci sia un po 'di ambiguità nello standard che permetta a qualcuno che vuole leggerlo in modo tale che semplicemente facendo invalido un puntatore si inneschi un comportamento indefinito (qualcosa sulla linea del termine non definito' uso '). Tuttavia, non sono un avvocato di lingua e non posso discutere questo caso. – SergeyA

+0

Il puntatore nullo è un valore di puntatore valido. ("Un valore valido di un puntatore oggetto rappresenta l'indirizzo di un byte in memoria (1.7) o un puntatore nullo" - 3.9.2 Tipi composti). – molbdnilo