Cosa è size_t in C?



Answers

size_t è un tipo senza segno. Quindi, non può rappresentare alcun valore negativo (<0). Lo usi quando conti qualcosa, e sei sicuro che non possa essere negativo. Ad esempio, strlen() restituisce una dimensione_t perché la lunghezza di una stringa deve essere almeno 0.

Nel tuo esempio, se il tuo indice del ciclo sarà sempre maggiore di 0, potrebbe avere senso utilizzare size_t o qualsiasi altro tipo di dati non firmato.

Quando usi un oggetto size_t , devi assicurarti che in tutti i contesti in cui viene usato, inclusa l'aritmetica, vuoi valori non negativi. Ad esempio, supponiamo di avere:

size_t s1 = strlen(str1);
size_t s2 = strlen(str2);

e vuoi trovare la differenza tra le lunghezze di str2 e str1 . Non puoi fare:

int diff = s2 - s1; /* bad */

Questo perché il valore assegnato a diff sarà sempre un numero positivo, anche quando s2 < s1 , perché il calcolo viene eseguito con tipi senza segno. In questo caso, a seconda di quale sia il tuo caso d'uso, potresti stare meglio usando int (o long long ) per s1 e s2 .

Ci sono alcune funzioni in C / POSIX che potrebbero / dovrebbero usare size_t , ma non per motivi storici. Ad esempio, il secondo parametro di fgets dovrebbe essere idealmente size_t , ma è int .

Question

Mi sto confondendo con size_t in C. So che viene restituito dall'operatore sizeof . Ma cos'è esattamente? È un tipo di dati?

Diciamo che ho un ciclo for :

for(i = 0; i < some_size; i++)

Dovrei usare int i; o size_t i; ?




Se sei il tipo empirico

echo | gcc -E -xc -include 'stddef.h' - | grep size_t

Uscita per GCC 4.8 Ubuntu 14.04 64 bit:

typedef long unsigned int size_t;

Si noti che stddef.h è fornito da GCC e non glibc in src/gcc/ginclude/stddef.h in GCC 4.2.

Interessanti presenze C99

  • malloc accetta size_t come argomento, quindi determina la dimensione massima che può essere allocata.

    E poiché viene anche restituito da sizeof , penso che limiti la dimensione massima di un array qualsiasi.

    Vedi anche: La dimensione massima di un array in C




Dalla mia comprensione, size_t è un intero unsigned una dimensione di bit abbastanza grande da contenere un puntatore dell'architettura nativa.

Così:

sizeof(size_t) >= sizeof(void*)



In generale, se stai iniziando a 0 e procedendo verso l'alto, usa sempre un tipo senza segno per evitare un overflow che ti porta in una situazione con valore negativo. Questo è di fondamentale importanza, perché se i limiti dell'array sono inferiori al massimo del ciclo, ma il massimo del tuo loop è maggiore del massimo del tuo tipo, ti avvolgeremo in negativo e potresti riscontrare un errore di segmentazione (SIGSEGV ). Quindi, in generale, non usare mai int per un ciclo che inizia da 0 e va verso l'alto. Usa un non firmato.




Poiché nessuno lo ha ancora menzionato, il significato linguistico primario di size_t è che la sizeof operator restituisce un valore di quel tipo. Allo stesso modo, il significato principale di ptrdiff_t è che sottrarre un puntatore da un altro produrrà un valore di quel tipo. Le funzioni di libreria che accettano lo fanno perché consentono a tali funzioni di funzionare con oggetti le cui dimensioni superano UINT_MAX su sistemi in cui tali oggetti potrebbero esistere, senza costringere i chiamanti a sprecare il codice passando un valore maggiore di "unsigned int" su sistemi in cui il tipo più grande sarebbe sufficiente per tutti gli oggetti possibili.




Related



Tags

c   int   size-t