문제

다음 코드를 고려하십시오.

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

여기에 관심이 있습니다 &myAry[numStrs]: numstrs는 5와 같습니다 &myAry[numStrs] 존재하지 않는 것을 가리 킵니다. 그만큼 육분의 하나 배열의 요소. 위 코드에는 이것의 또 다른 예가 있습니다. myVec.end(), 이것은 벡터의 일대일을 가리 킵니다 myVec. 존재하지 않는이 요소의 주소를 취하는 것은 완벽한 합법적입니다. 우리는 크기를 알고 있습니다 string, 우리는 C 스타일 배열의 6 번째 요소의 주소가 어디에 있는지 알고 있습니다. stringS를 가리켜 야합니다. 우리 가이 포인터 만 평가하고 절대로 피해를 입히지 않는 한, 우리는 괜찮습니다. 우리는 그것을 평등을 위해 다른 포인터와 비교할 수도 있습니다. STL은 다양한 반복자에 작용하는 알고리즘으로 항상이 작업을 수행합니다. 그만큼 end() 반복자는 끝을 지나가고 카운터 동안 루프가 계속 루핑됩니다. != end().

이제 이것을 고려하십시오.

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

이 코드는 합법적이고 잘 정의되어 있습니까? 다음과 같이 끝을지나 배열 요소의 주소를 취하는 것이 합법적이고 잘 정의되어 있습니다. &myAry[numStrs], 그렇게 척하는 것이 합법적이고 잘 정의되어야합니다. myPtr 배열이기도합니까?

도움이 되었습니까?

해결책

배열의 "끝"에 대한 포인터를 갖는 것은 합법적이고 UB가 아니며, 단일 객체는 길이 1의 배열에있는 것처럼 취급 될 수 있습니다. 그러나 사용해야합니다 ptr + 1 대신 기술로 인해 &ptr[1] Dereferencing을 한 다음 주소를 가져옵니다. 이것은 또한 적용됩니다 &array[size] 어울리는 array + size.

내가 알고있는 모든 플랫폼에서 기대하는대로 작동하지만 명백하게 올바른 양식을 사용하는 것이 얼마나 쉬운지를 감안할 때 대신 그렇게하지 않을 이유가 없습니다.

다른 팁

5.6/4 "첨가제 연산자"의 C ++ 표준은 다음과 같이 말합니다.

이 연산자의 목적 상, 비 어획 객체에 대한 포인터는 객체의 유형을 요소 유형으로 한 길이 배열의 첫 번째 요소에 대한 포인터와 동일합니다.

C99 표준 6.5.6/7은 본질적으로 동일하다고 말합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top