Pregunta

Considere el siguiente código:

#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;
}

De interés aquí es &myAry[numStrs]: numStrs es igual a 5, por lo que los puntos &myAry[numStrs] a algo que no existe; la sexto elemento en la matriz. Hay otro ejemplo de esto en el código anterior: myVec.end(), que apunta a uno-past-the-final de la myVec vector. Es perfecly legal de tomar la dirección de este elemento que no existe. Sabemos el tamaño de string, por lo que sabemos, donde la dirección del sexto elemento de una matriz de estilo de C strings debe apuntar a. Siempre y cuando nos limitamos a evaluar este puntero y nunca eliminar la referencia, estamos bien. Incluso podemos compararlo con otros indicadores para la igualdad. El STL hace esto todo el tiempo en los algoritmos que actúan sobre una serie de iteradores. Los puntos end() iterador más allá del final, y los bucles seguirá sonando mientras que un != end() mostrador.

Así que ahora considera lo siguiente:

#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;
}

¿Es este código legal y bien definido? Es legal y bien definida para tomar la dirección de un elemento de matriz más allá del final, como en &myAry[numStrs], por lo que debe ser legal y bien definida pretender que myPtr es también una matriz?

¿Fue útil?

Solución

es legal y no UB tener un puntero a "uno más allá del final" de una matriz, y cualquier objeto solo puede ser tratada como si fuera en una matriz de longitud 1; Sin embargo, es necesario utilizar ptr + 1 lugar debido al carácter técnico de &ptr[1] eliminación de referencias y luego tomar la dirección. Esto también se aplica a convertirse en &array[size] array + size.

Lo que tienes va a funcionar como se espera en todas las plataformas de las que yo sepa, pero teniendo en cuenta lo fácil que es usar la forma correcta de forma inequívoca, no veo ninguna razón para no hacerlo en su lugar.

Otros consejos

El estándar C ++ en 5,6 / 4 "operadores aditivos" dice:

  

A los efectos de estos operadores, un puntero a un objeto nonarray se comporta igual que un puntero al primer elemento de una matriz de longitud uno con el tipo de objeto como su tipo de elemento.

El estándar 6.5.6 / 7 C99 dice esencialmente el mismo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top