간단한 테스트 앱 :
cout << new int[0] << endl;
출력 :
0x876c0b8
따라서 작동하는 것처럼 보입니다. 표준은 이것에 대해 무엇을 말합니까? 빈 메모리 블록을 "할당"하는 것이 항상 합법적인가요?
간단한 테스트 앱 :
cout << new int[0] << endl;
출력 :
0x876c0b8
따라서 작동하는 것처럼 보입니다. 표준은 이것에 대해 무엇을 말합니까? 빈 메모리 블록을 "할당"하는 것이 항상 합법적인가요?
답변:
5.3.4 / 7에서
direct-new-declarator의 표현식 값이 0이면, 할당 함수가 호출되어 요소가없는 배열을 할당합니다.
3.7.3.1/2에서
크기가 0 인 요청으로 반환 된 포인터를 역 참조하는 효과는 정의되어 있지 않습니다.
또한
새로 요청한 공간의 크기가 0 인 경우에도 요청이 실패 할 수 있습니다.
즉, 할 수는 있지만 합법적으로 (모든 플랫폼에서 잘 정의 된 방식으로) 얻은 메모리를 참조 해제 할 수는 없습니다. 배열 삭제에만 전달할 수 있으므로 삭제해야합니다.
3.7.3.1/2의 문장에 첨부 된 흥미로운 각주 (표준의 규범적인 부분은 아니지만 설명 목적으로 포함)
[32. 의도는 malloc () 또는 calloc ()을 호출하여 연산자 new ()를 구현할 수 있도록하는 것이므로 규칙은 실질적으로 동일합니다. C ++은 널이 아닌 포인터를 리턴하기 위해 제로 요청이 필요하다는 점에서 C와 다릅니다.]
new[]
와 균형을 맞출 때마다 메모리 누수가 발생할 수 있다고 생각합니다 delete[]
. 특히, 호출 new[i]
할 때 배열의 크기를 저장하기 위해 할당하려는 메모리보다 약간 더 많은 메모리가 필요합니다 (나중에 delete[]
할당 해제 할 때 사용됨 )
예, 이와 같이 0 크기의 배열을 할당하는 것이 합법적입니다. 그러나 삭제해야합니다.
int ar[0];
는 새로운 것이 왜 불법 이라는 것을 알고 있습니다 .
sizeof (type)
결코 0을 반환하지 않을 것이라고 생각 합니다. 예를 들면 다음과 같습니다. stackoverflow.com/questions/2632021/can-sizeof-return-0-zero
표준은 이것에 대해 무엇을 말합니까? 빈 메모리 블록을 "할당"하는 것이 항상 합법적인가요?
모든 객체에는 고유 한 ID, 즉 고유 한 주소가 있으며 길이가 0이 아닌 것을 의미합니다 (0 바이트를 요청하면 실제 메모리 양이 자동으로 증가 함).
이러한 개체 중 하나 이상을 할당 한 경우 주소가 다른 것을 알 수 있습니다.
operator []
또한 어딘가에 배열의 크기를 저장합니다 ( isocpp.org/wiki/faq/freestore-mgmt#num-elems-in-new-array 참조 ). 따라서 구현시 데이터와 함께 바이트 수를 할당하면 바이트 수와 데이터에 0 바이트를 할당하여 1-last-last 포인터를 반환합니다.
operator new[]
은 다른 포인터를 반환해야 한다고 말합니다 . BTW new expression
에는 몇 가지 추가 규칙 (5.3.4)이 있습니다. new
크기가 0 인 것이 실제로 할당 해야하는 단서를 찾을 수 없었습니다. 죄송합니다. 귀하의 답변이 질문에 대한 답변이 아니라 논란의 여지가있는 진술을 제공하고 있음을 알게 되었기 때문에 공감했습니다.
new[]
구현시 동적 메모리가 매핑되지 않은 범위에서 주소를 반환 할 수 있으므로 주소 공간을 사용하는 동안 실제로 메모리를 사용하지 않습니다.
while(!exitRequested) { char *p = new char[0]; delete [] p; }
를 재활용하지 않고 루프를 실행하는 컴퓨터 는 주소 공간이 부족하기 전에 먼지로 붕괴되지만 32 비트 포인터가있는 플랫폼에서는 훨씬 덜 합리적인 가정.
으로 0
크기가 지정된 블록 을 할당하는 것은 완전히 합법적 입니다 new
. 액세스 할 유효한 데이터가 없기 때문에 유용한 정보를 얻을 수 없습니다.int[0] = 5;
불법입니다.
그러나 나는 표준 malloc(0)
이 돌아 오는 것과 같은 것들을 허용한다고 믿습니다.NULL
.
delete []
할당에서 다시 얻는 포인터 에도 여전히 필요합니다 .