Domanda

Si consideri il seguente codice:

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    string myAry[] = 
    {
        "Mary",
        "had", 
        "a",
        "Little",
        "Lamb"
    };
    const size_t numStrs = sizeof(myStr)/sizeof(myAry[0]);

    vector<string> myVec(&myAry[0], &myAry[numStrs]);

    copy( myVec.begin(), myVec.end(), ostream_iterator<string>(cout, " "));

    return 0;
}

Di interesse qui è &myAry[numStrs]: numStrs è uguale a 5, punti in modo &myAry[numStrs] a qualcosa che non esiste; sesto elemento dell'array. V'è un altro esempio di questo nel codice precedente: myVec.end(), che punta a un past the fine del myVec vettore. E 'in ottima posizione legale per prendere l'indirizzo di questo elemento che non esiste. Sappiamo che la dimensione del string, quindi sappiamo dove l'indirizzo dell'elemento 6 di una matrice C-stile di strings deve puntare a. Fino a quando valutiamo solo questo puntatore e mai dereferenziarlo, stiamo bene. Possiamo anche confrontarlo con altri puntatori per l'uguaglianza. STL fa questo tutto il tempo in algoritmi che agiscono su una serie di iteratori. I punti end() iteratore dopo la fine, e le anse continuano loop mentre un != end() contatore.

Così ora considerare questo:

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    string myStr = "Mary";
    string* myPtr = &myStr;
    vector<string> myVec2(myPtr, &myPtr[1]);

    copy( myVec2.begin(), myVec2.end(), ostream_iterator<string>(cout, " "));   

    return 0;
}

E 'questo codice legale e ben definito? È legale e ben definito per prendere l'indirizzo di un elemento di matrice oltre la fine, come in &myAry[numStrs], quindi dovrebbe essere legale e ben definita fingere che myPtr è anche un array?

È stato utile?

Soluzione

è legale e non UB avere un puntatore a "uno dopo la fine" di una matrice e ogni singolo oggetto può essere trattata come se fosse in un array di lunghezza 1; tuttavia, è necessario utilizzare ptr + 1 invece a causa della tecnicità del &ptr[1] dereferenziazione e poi prendendo l'indirizzo. Questo vale anche per &array[size] diventare array + size.

Quello che devi funzionerà come ci si aspetta su tutte le piattaforme di cui sono a conoscenza, ma dato quanto sia facile utilizzare il modulo senza ambiguità corretta, non vedo alcuna ragione per non farlo, invece.

Altri suggerimenti

Lo standard C ++ in 5,6 / 4 "operatori additivi", dice:

  

Ai fini di questi operatori, un puntatore ad un oggetto nonarray comporta come un puntatore al primo elemento di un array di lunghezza con il tipo di oggetto come tipo elemento.

Lo standard 6.5.6 / 7 C99 dice in sostanza la stessa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top