program tip

C ++는 동적 배열의 크기를 알려주지 않습니다.

radiobox 2020. 12. 2. 08:18
반응형

C ++는 동적 배열의 크기를 알려주지 않습니다. 그런데 왜?


C ++에서는 다음과 같이 동적으로 생성 된 배열의 크기를 얻을 수있는 방법이 없다는 것을 알고 있습니다.

int* a;
a = new int[n];

내가 알고 싶은 것은 : 왜? 사람들이 C ++ 사양에서 이것을 잊었습니까? 아니면 기술적 인 이유가 있습니까?

정보가 어딘가에 저장되어 있지 않습니까? 결국 명령

delete[] a;

얼마나 많은 메모리를 해제해야하는지 아는 것 같아서 delete[].NET의 크기를 아는 방법이있는 것 같습니다 a.


예를 들어 메모리 관리자는 특정 배수 (예 : 64 바이트)의 공간 만 할당하는 경우가 많습니다.

따라서 새로운 int [4], 즉 16 바이트를 요청할 수 있지만 메모리 관리자는 요청에 64 바이트를 할당합니다. 이 메모리를 해제하기 위해 요청한 메모리 양을 알 필요는 없으며 64 바이트 블록 하나만 할당하면됩니다.

다음 질문은 요청한 크기를 저장할 수 없습니까? 이것은 모든 사람이 지불 할 준비가되어 있지 않은 추가 비용입니다. 예를 들어 Arduino Uno에는 2k의 RAM 만 있으며 그 맥락에서 각 할당에 대해 4 바이트가 갑자기 중요해집니다.

해당 기능이 필요한 경우 std :: vector (또는 이와 동등한 것)가 있거나 더 높은 수준의 언어가 있습니다. C / C ++는 사용하기로 선택한만큼 적은 오버 헤드로 작업 할 수 있도록 설계되었으며, 이것이 하나의 예입니다.


이것은 "필요하지 않은 것을 지불하지 말라"는 기본 규칙의 후속입니다. int에는 소멸자가 없기 때문에 예제 delete[] a; 에서는 배열의 크기를 알 필요가 없습니다. 당신이 쓴 경우 :

std::string* a;
a = new std::string[n];
...
delete [] a;

그런 다음 delete소멸자를 호출해야합니다 (및 호출 할 수를 알아야 함).이 경우 new해당 수를 저장해야합니다. 그러나 모든 경우에 저장할 필요 가 없다는 점을 감안할 때 Bjarne은 액세스 권한을 부여하지 않기로 결정했습니다.

(돌아 보면 이것이 실수라고 생각합니다 ...)

심지어 함께 int물론, 뭔가 할당 된 메모리의 크기에 대해 알고있다, 그러나 :

  • 많은 할당자는 정렬 및 편의상의 이유로 크기를 편리한 배수 (예 : 64 바이트)로 반올림합니다. 할당자는 블록 길이가 64 바이트라는 것을 알고 있지만 그것이 n1 ...인지 16 인지 여부는 알지 못합니다 .

  • C ++ 런타임 라이브러리는 할당 된 블록의 크기에 액세스하지 못할 수 있습니다. 예를 들어, newdelete사용 mallocfree후드, 다음 C ++ 라이브러리에 의해 반환 된 블록의 크기를 알 수있는 방법이 없습니다 malloc. (보통 물론, newmalloc- 항상 아니지만 같은 라이브러리의 두 부분입니다.)


한 가지 근본적인 이유는 동적으로 할당 된 배열의 첫 번째 요소에 T대한 포인터와 다른 요소에 대한 포인터간에 차이가 없다는 것입니다 T.

포인터가 가리키는 요소의 수를 반환하는 가상의 함수를 생각해보십시오.
"크기"라고합시다.

정말 멋지죠?

모든 포인터가 동일하게 생성된다는 사실이 아니라면 :

char* p = new char[10];
size_t ps = size(p+1);  // What?

char a[10] = {0};
size_t as = size(a);     // Hmm...
size_t bs = size(a + 1); // Wut?

char i = 0;
size_t is = size(&i);  // OK?

첫 번째는 9, 두 번째 10, 세 번째 9및 마지막 이어야한다고 주장 할 수 1있지만이를 수행하려면 모든 단일 객체 에 "크기 태그"를 추가해야 합니다 .
A char는 64 비트 시스템에 128 비트의 스토리지 (정렬로 인해)가 필요합니다. 이것은 필요한 것보다 16 배 더 많습니다.
(위의 10 자 배열 a에는 최소 168 바이트가 필요합니다.)

이것은 편리 할 수 ​​있지만 용납 할 수 없을 정도로 비싸다.

물론 인수가 기본적으로 동적 할당의 첫 번째 요소에 대한 포인터 인 경우에만 잘 정의 된 버전을 상상할 수 operator new있지만 생각만큼 유용하지는 않습니다.


시스템의 일부가 크기에 대해 알아야 할 것이 맞습니다. 그러나 그 정보를 얻는 것은 아마도 메모리 관리 시스템의 API에 의해 다루어지지 않을 것입니다 ( malloc/를 생각하십시오 free). 요청한 정확한 크기는 반올림되었을 수 있기 때문에 알 수 없습니다.


operator delete나는 다음 과 같은 형태로 찾은 과부하에 대한 흥미로운 사례 가 있습니다.

void operator delete[](void *p, size_t size);

매개 변수 크기 는 기본적으로 void * p가 가리키는 메모리 블록의 크기 (바이트)로 보입니다. 이것이 사실이라면, 적어도 그것의 호출에 의해 전달 된 값이 있기를 바라는 것이 합리적 operator new이며, 따라서 배열에 저장된 요소의 수를 전달하기 위해 단순히 sizeof (type)나눌 필요가있을 것 입니다.

As for the "why" part of your question, Martin's rule of "don't pay for what you don't need" seems the most logical.


There's no way to know how you are going to use that array. The allocation size does not necessarily match the element number so you cannot just use the allocation size (even if it was available).

This is a deep flaw in other languages not in C++. You achieve the functionality you desire with std::vector yet still retain raw access to arrays. Retaining that raw access is critical for any code that actually has to do some work.

Many times you will perform operations on subsets of the array and when you have extra book-keeping built into the language you have to reallocate the sub-arrays and copy the data out to manipulate them with an API that expects a managed array.

Just consider the trite case of sorting the data elements. If you have managed arrays then you can't use recursion without copying data to create new sub-arrays to pass recursively.

Another example is an FFT which recursively manipulates the data starting with 2x2 "butterflies" and works its way back to the whole array.

To fix the managed array you now need "something else" to patch over this defect and that "something else" is called 'iterators'. (You now have managed arrays but almost never pass them to any functions because you need iterators +90% of the time.)


The size of an array allocated with new[] is not visibly stored anywhere, so you can't access it. And new[] operator doesn't return an array, just a pointer to the array's first element. If you want to know the size of a dynamic array, you must store it manually or use classes from libraries such as std::vector

참고URL : https://stackoverflow.com/questions/36471101/c-doesnt-tell-you-the-size-of-a-dynamic-array-but-why

반응형