16

는, 당신은 같은 것을 할 수 있습니다컴파일러가`delete [] p` 대`delete p []`를 필요로하는 이유는 무엇입니까? 동적 배열을 할당 할 경우 C++에서

int *p; 
p = new int[i]; // i is some number 

을하지만, 배열, 당신이 할을 삭제 ...

delete[] p; 

왜 ISN ' 그것 delete p[]? 그것이 원래 만들어 졌던 방식과 더 대칭 적이 지 않습니까? 언어가 이렇게 설계된 이유는 무엇입니까 (있는 경우)?

+8

왜 downvote/vote 닫을까요? 질문을 개선하기 위해 무엇을 할 수 있습니까? – Michael0x2a

+5

@Deflect : 그건 내 것이 었습니다. 보통 '이 언어 구조가 선택된 이유는 무엇입니까?' 객관적이고 합리적인 대답이 없기 때문에 질문은 단순히 건설적인 것이 아닙니다. 그러나,이 경우에는 몇 가지 알맞은 이유가 있으므로 너무 빨리 판단 할 수 있습니다 (나는 내 ​​downvote를 아주 빨리 제거했습니다). – KillianDS

+1

@KillianDS : 좋습니다. 답장을 보내 주셔서 감사합니다. [내가 완전히 오프베이스가 아니란 것을 안심 시키십시오] – Michael0x2a

답변

29

한 가지 이유는 이러한 사례를보다 분명하게 만들 수 있습니다.

int ** p; 
delete[] p 
delete p[1]; 

delete p[] 인 경우 다음 하나 개의 문자 오류가 꽤 불쾌한 consquences있을 것입니다.

+13

이것은 특히 초기 C++에서'[] '의 요소 수를 지정해야한다는 점에서 사실입니다. –

+4

@JamesKanze : 그게 내 대답 인 것 같네. 'delete p [4]'는 모호합니다. – GManNickG

+0

@GManNickG 바로. –

2

매개 변수로 함수 (또는 연산자)를 전달할 때 배열이 포인터로 쇠퇴하기 때문입니다. 그래서 p [] 삭제는 간단히 p를 삭제하는 것과 같습니다.

[편집] 특수 템플릿 연산자로서 삭제할 수 있습니다. 운영자는 p와 p [] 사이를 구별하여 올바른 "전문화"(비 어레이 또는 어레이 삭제)를 선택할 수 있어야합니다. 그러나 템플리트 인수 공제 규칙은이 선택을 불가능하게 만듭니다 (인수를 추론 할 때 p []와 p 사이를 구분할 수없는 어레이 붕괴로 인해).

그래서 우리는 모두 casees에 대한을 삭제 이름 와 연산자를 사용하고 다른 연산자 [] 삭제 소개 할 필요가 없습니다 배열 사건에 대한 diffrent 이름 (접미사 [] 연산자의 이름의 일부로 취급 될 수있다)과 함께.

[편집 2] 참고. delete p []는 현재 표준에 따라 유효한 sintax가 아닙니다. 위의 추론은 기존의 C++ 개념을 사용하여 delete p []를 해석하려고 시도하는 경우에만 문제를 제기 할 수 있습니다.

+0

아니요, 그것은 동일하지 않습니다. 다른 것을 대신 사용하는 것은 정의되지 않은 동작입니다. – sharptooth

+0

@sharptooth :? 포인터 대신 템플릿 함수에 배열을 전달하는 것은 UB입니까? 나는 templated 연산자에 대한 delete에 대해 생각한다. 그리고이 연산자는 인수를 추론 할 때 p []와 p를 구별 할 수 없기 때문에 적절한 전문화를 선택할 수 없다.그래서 우리는 동일한 연산자 이름을 사용하는 대신 배열에 특별한 연산자 delete []를 써야합니다. – user396672

+0

'delete []'에'new'가 반환 한 포인터를 전달하는 것은 UB – sharptooth