Qual è la dimensione massima di un array in C?

Comprendo che l’hardware limiterà la quantità di memoria allocata durante l’esecuzione del programma. Tuttavia, la mia domanda è senza riguardo per l’hardware. Supponendo che non ci fosse un limite alla quantità di memoria, non ci sarebbe limite alla matrice?

Non esiste un limite fisso per la dimensione di un array in C.

La dimensione di ogni singolo object, incluso qualsiasi object matrice, è limitata da SIZE_MAX , il valore massimo di tipo size_t , che è il risultato dell’operatore sizeof . (Non è del tutto chiaro se lo standard C consente oggetti più grandi di SIZE_MAX byte, ma in pratica tali oggetti non sono supportati, vedi nota.) Poiché SIZE_MAX è determinato dall’implementazione e non può essere modificato da alcun programma, impone un limite superiore di SIZE_MAX byte per ogni singolo object. (Questo è un limite superiore, non un limite superiore, le implementazioni possono, e in genere lo fanno, imporre limiti più piccoli).

La larghezza del tipo void* , un tipo generico di puntatore, impone un limite superiore alla dimensione totale di tutti gli oggetti in un programma in esecuzione (che può essere maggiore della dimensione massima di un singolo object).

Lo standard C impone limiti inferiori, ma non superiori, su queste dimensioni fisse. Nessuna implementazione C conforms può supportare oggetti di dimensioni infinite, ma in linea di principio può supportare oggetti di qualsiasi dimensione finita. I limiti superiori sono imposti dalle singole implementazioni C, dagli ambienti in cui operano, dalla fisica e non dalla lingua.

Ad esempio, un conforms attuazione potrebbe avere SIZE_MAX uguale a 2 1024 -1, il che significa che potrebbe in linea di principio gli oggetti fino a 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137215 byte.

Buona fortuna a trovare hardware che supporti effettivamente tali oggetti.

Nota : non esiste una regola esplicita che nessun object possa essere più grande di SIZE_MAX byte. Non è ansible applicare utilmente l’operatore sizeof a tale object, ma come qualsiasi altro operatore, sizeof può overflow; questo non significa che non potresti eseguire operazioni su un tale object. Ma in pratica qualsiasi implementazione sana renderà size_t abbastanza grande da rappresentare la dimensione di qualsiasi object che supporta.

C99 5.2.4.1 “Limiti di traduzione” dimensione minima

L’implementazione deve essere in grado di tradurre ed eseguire almeno un programma che contenga almeno un’istanza di ciascuno dei seguenti limiti: 13)

  • 65535 byte in un object (solo in un ambiente ospitato)

13) Le implementazioni dovrebbero evitare di imporre limiti di traduzione fissi quando ansible.

Ciò suggerisce che un’implementazione conforms potrebbe rifiutarsi di compilare un object (che include matrici) con più di short byte.

PTRDIFF_MAX sembra essere un limite pratico per gli oggetti array statici

Lo standard C99 6.5.6 operatori additivi dice:

9 Quando due puntatori vengono sottratti, entrambi puntano a elementi dello stesso object matrice o uno dopo l’ultimo elemento dell’object matrice; il risultato è la differenza degli indici dei due elementi dell’array. La dimensione del risultato è definita dall’implementazione e il suo tipo (un tipo intero con ptrdiff_t ) è definito da ptrdiff_t nell’intestazione . Se il risultato non è rappresentabile in un object di quel tipo, il comportamento non è definito.

Il che implica che in teoria gli array più grandi di ptrdiff_t sono consentiti, ma in questo caso non è ansible prendere la differenza dei loro indirizzi in modo portabile.

Quindi forse per questo motivo, GCC sembra limitarti a ptrdiff_t . Questo è anche citato in: Perché la dimensione massima di un array “troppo grande”?

Ho verificato empiricamente questo con main.c :

 #include  uint8_t a[(X)]; int main(void) { return 0; } 

e poi a Ubunbu il 17.10:

 $ arm-linux-gnueabi-gcc --version arm-linux-gnueabi-gcc (Ubuntu/Linaro 7.2.0-6ubuntu1) 7.2.0 Copyright (C) 2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ printf ' > #include  > PTRDIFF_MAX > SIZE_MAX > ' | arm-linux-gnueabi-cpp | tail -n2 (2147483647) (4294967295U) $ PTRDIFF_MAX == 2147483647 == 2^31 - 1 $ $ # 2lu < < 30 == 2^31 == PTRDIFF_MAX + 1 $ arm-linux-gnueabi-gcc -std=c99 -DX='(2lu << 30)' main.c ac:5:9: error: size of array 'a' is too large uint8_t a[(X)]; ^ $ $ # PTRDIFF_MAX $ arm-linux-gnueabi-gcc -std=c99 -DX='(2lu << 30) - 1lu' main.c $ 

Guarda anche

  • Ci sono limitazioni di dimensione per le strutture C?
  • Qual è il tipo corretto per gli indici di array in C?

Una macchina a 64 bit potrebbe teoricamente indirizzare un massimo di 2 ^ 64 byte di memoria.

Senza riguardo per la memoria, la dimensione massima di un array è limitata dal tipo di intero utilizzato per indicizzare l’array.

Immagino che il più grande array teorico sia il valore massimo di “unsigned long” (o qualunque sia il numero intero più grande dell’ultimo standard / il tuo compilatore supporta)

La dimensione del puntatore limiterà la memoria a cui è ansible accedere. Anche se l’hardware offre supporto per la memoria illimitata, se il tipo di dati più grande che si è in grado di utilizzare è 64 bit, sarà ansible accedere solo a 2 ^ 64 byte di memoria.

Stavo cercando un modo per determinare la dimensione massima per un array. Questa domanda sembra chiedere la stessa cosa, quindi voglio condividere le mie conclusioni.

Inizialmente, C non fornisce alcuna funzione per determinare il numero massimo di elementi allocabili in una matrice in fase di compilazione. Questo perché dipenderà dalla memoria disponibile nella macchina in cui verrà eseguita.

D’altra parte, ho trovato, che le funzioni di allocazione della memoria ( calloc() e malloc() ) consentono di allocare array più grandi. Inoltre, queste funzioni consentono di gestire gli errori di allocazione della memoria di runtime.

Spero possa aiutare.