Pergunta

Considere o seguinte 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 interesse aqui é &myAry[numStrs]: numStrs é igual a 5, de modo &myAry[numStrs] aponta para algo que não existe; sexto elemento na matriz. Há um outro exemplo deste no código acima: myVec.end(), o que aponta para um passado-a-extremidade do myVec vector. É perfecly legal para tomar o endereço deste elemento que não existe. Sabemos o tamanho da string, por isso sabemos onde o endereço da 6ª elemento de uma matriz C-estilo de strings deve apontar para. Enquanto nós só avaliar este ponteiro e nunca desreferenciava isso, estamos bem. Podemos até compará-lo com outros ponteiros para a igualdade. O STL faz isso o tempo todo em algoritmos que agem sobre uma gama de iteradores. Os pontos end() iteradoras últimos final, e os loops manter looping enquanto um contador != end().

Agora considere o seguinte:

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

É este código legal e bem definida? É legal e bem definido para obter o endereço de um elemento de matriz após o final, como em &myAry[numStrs], por isso deve ser legal e bem definido para fingir que myPtr é também um array?

Foi útil?

Solução

é legal e não UB ter um ponteiro de "um após o final" de uma matriz, e um único objecto pode ser tratada como se fosse em uma matriz de um comprimento; no entanto, você precisa usar ptr + 1 vez devido à tecnicidade da dereferencing &ptr[1] e, em seguida, tomando o endereço. Isso também se aplica a &array[size] tornando array + size.

O que você tem vai funcionar como você espera em todas as plataformas do qual eu estou ciente, mas dado o quão fácil é de usar a forma inequivocamente correta, não vejo razão para não fazer isso em seu lugar.

Outras dicas

O padrão C ++ em 5,6 / 4 "operadores aditivos" diz:

Para efeitos destes operadores, um apontador para um objecto nonarray se comporta da mesma como um ponteiro para o primeiro elemento de uma matriz de um comprimento com o tipo do objecto como o seu tipo de elemento.

A norma 6.5.6 / 7 C99 diz essencialmente o mesmo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top