2009-03-22 19 views
41

Come si trova in fase di esecuzione la dimensione dell'array? dove sono archiviate le informazioni sulla dimensione dell'array o sui limiti della matrice?Come funziona sizeof (array)

risposta

55

sizeof(array) è implementata interamente dal compilatore C. Nel momento in cui il programma viene collegato, quella che sembra una chiamata sizeof() è stata convertita in una costante.

Esempio: quando si compila il codice C:

#include <stdlib.h> 
#include <stdio.h> 
int main(int argc, char** argv) { 
    int a[33]; 
    printf("%d\n", sizeof(a)); 
} 

si ottiene

.file "sz.c" 
    .section  .rodata 
.LC0: 
    .string "%d\n" 
    .text 
.globl main 
    .type main, @function 
main: 
    leal 4(%esp), %ecx 
    andl $-16, %esp 
    pushl -4(%ecx) 
    pushl %ebp 
    movl %esp, %ebp 
    pushl %ecx 
    subl $164, %esp 
    movl $132, 4(%esp) 
    movl $.LC0, (%esp) 
    call printf 
    addl $164, %esp 
    popl %ecx 
    popl %ebp 
    leal -4(%ecx), %esp 
    ret 
    .size main, .-main 
    .ident "GCC: (GNU) 4.1.2 (Gentoo 4.1.2 p1.1)" 
    .section  .note.GNU-stack,"",@progbits 

Il $132 in mezzo è la dimensione della matrice, 132 = 4 * 33. Si noti che non c'è no call sizeof istruzione - a differenza di printf, che è una funzione reale.

+1

lol! Questo mi insegnerà a non controllare di aver messo le mie mani nel posto giusto ...grazie per la correzione Rob –

+1

Ah, ora capisco, David deve essere un dattilografo cieco con una disfunzione tattile alle estremità delle dita :-) Divertente come la c ed e andava bene - ho dovuto controllare che ogni altra lettera fosse uno a sinistra della posizione corretta. – paxdiablo

+1

Immagino che la mia mano sinistra fosse nel posto giusto ma la mia mano destra è stata spostata di una chiave a sinistra ... sembra un errore facile da fare - se stai scrivendo una risposta mentre guardi la TV ;-) –

7

sizeof() funziona solo per una matrice di dimensioni fisse (che può essere statica, basata su stack o in una struttura).

Se lo si applica a un array creato con malloc (o nuovo in C++) si otterrà sempre la dimensione di un puntatore.

E sì, questo si basa sulle informazioni sulla compilazione del tempo.

+0

Gli array di dimensioni fisse non sono necessariamente basati sullo stack. C non ha un nuovo operatore. – ysth

+0

Hai ragione, modifico un po '. –

+3

Hai dimenticato C99 VLA - array di lunghezza variabile. –

2

sizeof (Array) viene visualizzato in fase di compilazione, non in fase di esecuzione. Le informazioni non sono memorizzate.

Siete forse interessati a implementare il controllo dei limiti? Se è così, ci sono diversi modi per farlo.

5

sizeof dà la dimensione della variabile, non la dimensione dell'oggetto che si sta indicando (se ce n'è uno.) sizeof(arrayVar) restituirà la dimensione della matrice in byte se e solo se arrayVar è dichiarata in ambito come array e non un puntatore.

Ad esempio:

char myArray[10]; 
char* myPtr = myArray; 

printf("%d\n", sizeof(myArray)) // prints 10 
printf("%d\n", sizeof(myPtr)); // prints 4 (on a 32-bit machine) 
17

sizeof è tempo di compilazione puro in C++ e C prima di C99. A partire dalla C99 ci sono gli array di lunghezza variabile:

// returns n + 3 
int f(int n) { 
    char v[n + 3]; 

    // not purely a compile time construct anymore 
    return sizeof v; 
} 

che valuterà il sizeof operando, perché n non è ancora noto al momento della compilazione. Che solo si applica a matrici di lunghezza variabile: altri operandi o tipi eseguono ancora dimensioni di calcolo in fase di compilazione. In particolare, gli array con dimensioni note al momento della compilazione sono ancora gestiti come in C++ e C89. Di conseguenza, il valore restituito da sizeof non è più una costante di tempo di compilazione (espressione costante). Non è possibile utilizzarlo quando è richiesto un valore di questo tipo, ad esempio quando si inizializzano variabili statiche, a meno che un'estensione specifica del compilatore lo consenta (lo standard C consente a un'implementazione di avere estensioni a ciò che considera come costante).

+4

Bene quello lei parla di VLA C99. Tuttavia, la tua risposta dovrebbe sottolineare che anche in C99, gli array di dimensioni fisse hanno le loro dimensioni calcolate in fase di compilazione - sono solo VLA che hanno le loro dimensioni calcolate in fase di runtime. E forse, di conseguenza, non puoi sempre usare 'sizeof (array)' come costante in C99. –

+0

oh giusto. non ho visto questa ambiguità nella mia risposta. –

+0

ok, ora di dormire per me ora. più tardi mi sveglierò e urlerò di tutti quegli errori di battitura nelle mie risposte: p –