delete []는 피연산자 배열의 크기를 어떻게 “알고”있습니까? [] set; 배열의 경계를에

Foo* set = new Foo[100];
// ...
delete [] set;

배열의 경계를에 전달하지 않습니다 delete[]. 그러나 그 정보는 어디에 저장되어 있습니까? 표준화 되었습니까?



답변

힙에 메모리를 할당하면 할당자는 할당 한 메모리 양을 추적합니다. 이것은 일반적으로 할당 된 메모리 직전에 “헤드”세그먼트에 저장됩니다. 그렇게하면 메모리를 비울 때 할당 해제자는 메모리를 얼마나 비울 수 있는지 정확히 알 수 있습니다.


답변

컴파일러의 접근법 중 하나는 조금 더 많은 메모리를 할당하고 헤드 요소에 요소 수를 저장하는 것입니다.

수행 방법 예 :

여기

int* i = new int[4];

컴파일러는 sizeof(int)*5바이트 를 할당 합니다.

int *temp = malloc(sizeof(int)*5)

sizeof(int)바이트 에 “4”를 저장 합니다

*temp = 4;

그리고 설정 i

i = temp + 1;

따라서 i5가 아닌 4 개의 요소로 구성된 배열을 가리 킵니다.

그리고 삭제

delete[] i;

다음과 같은 방식으로 처리됩니다.

int *temp = i - 1;
int numbers_of_element = *temp; // = 4
... call destructor for numbers_of_element elements
... that are stored in temp + 1, temp + 2, ... temp + 4 if needed
free (temp)


답변

정보는 표준화되지 않았습니다. 그러나이 정보를 다루는 플랫폼에서 첫 번째 요소 직전에 메모리에 저장됩니다. 따라서 이론적으로 액세스하여 검사 할 수 있지만 그만한 가치는 없습니다.

또한 delete의 배열 버전이 적절한 양의 메모리를 비워야하는 것으로 알고 적절한 소멸자 수를 호출해야한다는 것을 알기 때문에 new []로 메모리를 할당 할 때 delete []를 사용해야하는 이유도 있습니다 객체를 위해.


답변

기본적으로 메모리에 다음과 같이 배열됩니다.

[정보] [요청한 …]

여기서 info는 할당 된 메모리 양을 저장하기 위해 컴파일러에서 사용하는 구조입니다.

이것은 구현에 따라 다릅니다.


답변

이것은 사양에있는 것이 아니며 구현에 따라 다릅니다.


답변

C ++ 표준에서 컴파일러에 따라 정의됩니다. 이것은 컴파일러의 마술을 의미합니다. 하나 이상의 주요 플랫폼에서 사소한 정렬 제한으로 인해 중단 될 수 있습니다.

에 의해 delete[]반환 된 포인터에 대해서만 정의되며 new[],에 의해 반환 된 포인터와 같지 않을 수 있음을 인식함으로써 가능한 구현에 대해 생각할 수 있습니다 operator new[]. 와일드에서 한 구현은에서 반환 된 첫 번째 int에 배열 수를 저장하고 그 이후로 포인터 오프셋 operator new[]new[]반환하는 것입니다. (이것이 사소한 정렬이 깨질 수있는 이유 new[]입니다.)

있음을 알아 두셔야합니다 operator new[]/operator delete[]! = new[]/delete[].

또한 이것은 C가 할당 한 메모리 크기를 알고있는 방식과 직교합니다 malloc.


답변

‘삭제’할 배열은 ‘new’연산자를 한 번만 사용하여 만들어야했기 때문입니다. ‘new’작업은 해당 정보를 힙에 넣어야합니다. 그렇지 않으면, 새로운 추가 사용은 힙이 끝나는 위치를 어떻게 알 수 있습니까?