programing

어레이의 최대 사이즈가 너무 큰 이유는 무엇입니까?

prostudy 2022. 6. 2. 21:30
반응형

어레이의 최대 사이즈가 너무 큰 이유는 무엇입니까?

저도 이 답변과 같은 인상을 받고 있습니다.size_t는 표준으로 항상 특정 시스템의 가능한 가장 큰 유형을 수용할 수 있는 크기를 보증합니다.

단, 이 코드는 gcc/Mingw에서 컴파일 할 수 없습니다.

#include <stdint.h>
#include <stddef.h>

typedef uint8_t array_t [SIZE_MAX];

오류: 어레이 'array_t'의 크기가 너무 큽니다.

제가 이 기준에서 뭔가 잘못 알고 있는 건가요?size_t특정 구현에 대해 너무 큰 크기를 허용합니까?아니면 밍구의 또 다른 벌레인가요?


편집: 추가 조사에 따르면

typedef uint8_t array_t [SIZE_MAX/2];   // does compile
typedef uint8_t array_t [SIZE_MAX/2+1]; // does not compile

그건 공교롭게도 같은 거야

#include <limits.h>

typedef uint8_t array_t [LLONG_MAX];           // does compile
typedef uint8_t array_t [LLONG_MAX+(size_t)1]; // does not compile

그래서 저는 이것이 Mingw의 버그라고 믿고 싶습니다.왜냐하면 부호 있는 정수형을 기준으로 최대 허용 크기를 설정하는 것은 의미가 없기 때문입니다.

SIZE_MAX / 2 의 제한은, 실장상의 size_t 와 ptrdiff_t 의 정의에 근거해, ptrdiff_t 와 size_t 의 타입이 같은 폭을 가지는 것을 선택합니다.

C Standard에서는1 size_t 유형은 부호 없음, ptrdiff_t 유형은 부호 있음이어야 합니다.

두 포인터의 차이에 따른 결과에는 항상 ptrdiff_t 유형이 있습니다2.즉, 실장에서는 오브젝트의 크기를 PTRDIFF_MAX로 제한해야 합니다.그렇지 않으면 2개의 포인터의 유효한 차이를 ptrdiff_t 타입으로 나타낼 수 없기 때문에 정의되지 않은 동작이 발생합니다.

따라서 SIZE_MAX / 2 값은 PTRIFF_MAX 값과 동일합니다.구현에서 최대 개체 크기를 SIZE_MAX로 설정할 경우 ptrdiff_t 유형의 폭을 늘려야 합니다.그러나 개체의 최대 크기를 SIZE_MAX/2로 제한하는 것이 훨씬 쉬우며, 따라서 ptrdiff_t 유형이 size_t 유형보다 크거나 같은 양의 범위를 갖는 것이 좋습니다.

Standard는 이 주제에 대해 다음과4 같은 의견을 제공한다3.


(ISO/IEC 9899:201x에서 인용)

1 (7.19 공통 정의 2)
종류는 다음과 같습니다.
ptrdiff_t
2개의 포인터를 뺀 결과의 부호 있는 정수형입니다.
size_t
연산자 크기 결과의 부호 없는 정수 유형입니다.

2 (6.5.6 가법연산자 9)
2개의 포인터가 감산되면 양쪽 모두 같은 배열 객체의 요소 또는 배열 객체의 마지막 요소 뒤에 있는 요소를 가리켜야 합니다.그 결과 두 배열 요소의 첨자 차이가 발생합니다.결과의 사이즈는 실장 정의이며, 그 타입(부호 있는 정수 타입)은 헤더에 정의되어 있다.ptrdiff_t결과를 해당 유형의 개체로 나타낼 수 없는 경우 동작은 정의되지 않습니다.

3 (K.3.4 정수 타입 3)
객체의 크기가 매우 큰 것은 객체의 크기가 잘못 계산되었음을 나타내는 경우가 많습니다.예를 들어, 음수는 size_t와 같은 부호 없는 유형으로 변환할 때 매우 큰 양수로 표시됩니다.또한 일부 구현에서는 type size_t로 나타낼 수 있는 최대값만큼 큰 개체를 지원하지 않습니다.

4 (K.3.4 정수형 4)
이러한 이유로 프로그래밍 오류를 감지하기 위해 개체 크기 범위를 제한하는 것이 유용할 수 있습니다.주소 공간이 큰 머신을 대상으로 하는 실장에서는 지원되는 가장 큰 오브젝트의 크기 또는 (SIZE_MAX >> 1) 중 작은 것으로 정의할 것을 권장합니다.단, 이 제한이 정규 오브젝트의 크기보다 작지만 매우 큰 오브젝트의 크기보다 작을 경우에도 마찬가지입니다.주소 공간이 작은 머신을 대상으로 하는 구현에서는 RSIZE_MAX를 SIZE_MAX로 정의할 수 있습니다.즉, 런타임 제약 위반으로 간주되는 오브젝트 크기는 존재하지 않습니다.

의 범위size_t는 구현에서 지원되는 가장 큰 오브젝트의 크기를 저장하기에 충분한 것을 보증합니다.그 반대는 사실이 아닙니다.사이즈가 다음 범위 전체를 채우는 오브젝트를 작성할 수 없습니다.size_t.

이러한 상황에서 질문은 다음과 같습니다.SIZE_MAX대표할 수식어때요?지원되는 최대 개체 크기?또는 에서 나타내는 가장 큰 값size_t정답은 후자, 즉 후자입니다.SIZE_MAX(size_t) -1. 오브젝트를 작성할 수 있는 것은 보증되지 않습니다.SIZE_MAX바이트가 크다.

그 이면에는 또size_t구현은 또한ptrdiff_t이는 동일한 배열 개체를 가리키는 두 포인터의 차이를 저장하기 위한 것입니다(단, 보장되지 않음).이후 유형ptrdiff_t이 서명되면 구현에는 다음 선택지가 있습니다.

  1. 크기의 어레이 개체 허용SIZE_MAX만들어 내다ptrdiff_t 보다 넓은size_t1비트 정도는 더 넓어져야 합니다.그런ptrdiff_t크기의 배열을 가리키는 두 포인터의 차이를 수용할 수 있다SIZE_MAX또는 그 이하.

  2. 크기의 어레이 개체 허용SIZE_MAX및 사용ptrdiff_t같은 폭의size_t포인터가 다음보다 먼 경우 포인터 감산이 오버플로우하여 정의되지 않은 동작을 일으킬 수 있다는 사실을 받아들입니다.SIZE_MAX / 2 elements apart. The language specification does not prohibit this approach.

  3. Use ptrdiff_t of the same width as size_t and restrict the maximum array object size by SIZE_MAX / 2. Such ptrdiff_t can accommodate any difference between two pointers pointing into an array of size SIZE_MAX / 2 or smaller.

You are simply dealing with an implementation that decided to follow the third approach.

It looks very much like implementation-specific behaviour.

I'm running here Mac OS, and with gcc 6.3.0 the biggest size I can compile your definition with is SIZE_MAX/2; with SIZE_MAX/2 + 1 it does not compile anymore.

On the other side, witch clang 4.0.0 the biggest one is SIZE_MAX/8, and SIZE_MAX/8 + 1 breaks.

Just reasoning from scratch, size_t is a type that can hold the size of any object. The size of any object is limited by the width of the address bus (ignoring multiplexing and systems that can handle eg 32 and 64 bit code, call that "code width"). Anologous to MAX_INT which is the largest integer value, SIZE_MAX is the largest value of size_t. Thus, an object of size SIZE_MAX is all addressable memory. It s reasonable that an implementation flags that as an error, however, I agree that it is an error only in a case where an actual object is allocated, be it on the stack or in global memory. (A call to malloc for that amount will fail anyway)

ReferenceURL : https://stackoverflow.com/questions/42574890/why-is-the-maximum-size-of-an-array-too-large

반응형