길이가 0 인 배열에 대한 포인터의 속성


21

치다

int main()
{
    auto a = new int[0];
    delete[] a; // So there's no memory leak
}

복사 초기화와 삭제 사이에 포인터를 읽을 수 a + 1있습니까?

또한 언어는 컴파일러 anullptr?


2
@Fareanor : a확실히 읽을 수 있습니다 (반드시 역 참조 할 수는 없습니다).
Bathsheba

8
@RasmiRanjanNayak : 그거 혐오.
Bathsheba

2
@RasmiRanjanNayak Oh my ... no
Ted Lyngmo

1
@TedLyngmo : "에서 포인터를 읽을 때"라고 말하면 a + 1다음 코드가 auto b = a + 1;정의되지 않은 동작입니까? (그렇다고 생각합니다).
Bathsheba

2
@ Ayxan 나는 0실제로 런타임까지 알지 못하는 표현의 결과 인 경우를 추측 합니다. new int[0]안전 하기 때문에 일부 분기 / 특수 사례에 대한 걱정을 덜 수 있습니다. std::vectorwith 를 초기화한다고 상상해보십시오 std::vector<int> v(0);.
scohe001

답변:


3
    auto a = new int[0];

[basic.compound.3] 에 따르면 저장된 값 a은 다음 중 하나 여야합니다.

  1. (형식의 개체에 대한 포인터 int)
  2. 객체의 끝을 지나는 포인터
  3. 없는
  4. 무효

유형의 객체가 생성되지 않았으므로 첫 번째 가능성을 배제 할 수 있습니다 int. C ++에서 널이 아닌 포인터를 리턴해야하므로 세 번째 가능성은 배제됩니다 ( [basic.stc.dynamic.allocation.2] 참조 ). 따라서 우리는 두 가지 가능성이 있습니다 : 객체의 끝을 지나는 포인터 또는 유효하지 않은 포인터.

나는 a최후의 포인터로 생각하는 경향이 있지만, 그것을 확실하게 확립 할 수있는 평판 좋은 참조는 없습니다. (그러나 [basic.stc] 에서는 delete이 포인터 가 어떻게 사용되는지 알 수 있습니다 .) 따라서이 답변에서 두 가지 가능성을 모두 접할 것입니다.

복사 초기화와 삭제 사이에 포인터를 읽을 수 a + 1있습니까?

위의 가능성에 관계없이 [expr.add.4] 에 명시된대로 동작은 정의되지 않습니다 .

경우 a과거 - 더 - 엔드 포인터,이어서,이를 인덱스 가상 소자 포인트 여겨진다 0없는 요소 배열. 정수를 추가 j하는 a경우에만 정의된다 0≤0+j≤n여기서, n상기 어레이의 크기이다. 우리의 경우, n제로, 그래서 합이 a+j경우에만 정의되어 j있다 0. 특히 추가 1는 정의되지 않습니다.

a유효하지 않은 경우 에는 "그렇지 않으면 동작이 정의되지 않습니다." (정말로 정의 된 경우에는 유효한 포인터 값만 포함됩니다.)

또한 언어는 컴파일러 anullptr?

아니요. 위에서 언급 한 [basic.stc.dynamic.allocation.2]에서 : "요청이 성공하면 교체 가능한 할당 함수가 반환 한 값은 널이 아닌 포인터 값 입니다. " 또한 C ++ (C는 아님)에 제로 요청에 대한 응답으로 null이 아닌 포인터가 필요하다는 각주 가 있습니다 .


1
포인터 값이 유효하지 않으면 eel.is/c++draft/basic.stc#4
TC

@TC True, 이는 유효하지 않은 포인터 값이 될 수 없음을 강력하게 암시합니다.
JaMiT

23

의 결과로 최근 CWG 반사판 토론 당 편집 문제 3178 , new int[0]현재 무엇이라고 낸다 "과거 - 더 - 끝"포인터 값 .

뒤에는a 널 이 될 수 없으며 [expr.add] / 4에a + 1 의해 정의되지 않습니다 .


4
"편집 문제 3178의 결과로 최근 CWG 리플렉터 논의에 따라 new int[0]현재"종료 "포인터 값을 생성합니다" 이것은 정확하지 않습니다. 토론이 많지 않았습니다. 한 사람은 값이 "객체의 끝을 지나치는 포인터"여야한다고 제안했으며, 0요소 가있는 배열의 경우 끝을 지나갈 대상이 없기 때문에이 문에 의문이 제기되었습니다 .
언어 변호사

@LanguageLawyer a + 1어떤 경우에도 정의되지 않은 의심의 여지가 없으므로 요점은 anull 일 수 있는지 여부에만 관련이 있습니까?
MM

의도 된 의미론에 대해 의견이 일치하지 않았거나이 범주의 포인터 값 범주에 대한 현재 이름이이 시나리오에 적합하지 않은 것으로 보입니다.
TC

@MM 나는 그것이 a + 1정의되지 않았다고 생각 하고 결과 포인터 값은 "종료 포인터"라고합니다. 나는 대답이 잘못되었다고 말하는 것이 아닙니다. 결과가 "종료 후 포인터"라고 지정하는 것만으로도 문제를 해결하기에 충분하다는 합의와 긴 토론이 있었기 때문에 이해할 수 없기 때문에 약간 정확하지 않습니다. "끝을 지나친 포인터"의 문제점은 그것이 어떤 객체의 끝을 지나서 1그런 포인터 값에서 빼면 객체에 대한 포인터를 제공한다는 것입니다 0.
언어 변호사

2
@Bathsheba 결함이있는 문구에 대해 더 권위있는 것이 있다고 생각하십니까?
언어 변호사
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.