2009-03-04 8 views
11

Ho impostato il buffer sulla dimensione 100. Visualizzo il buffer nella funzione principale in cui viene dichiarato il buffer. Tuttavia, quando passo il buffer alla funzione e ottengo la dimensione di '4', pensavo che dovesse essere 100, poiché questa è la dimensione del buffer che ho creato in I . uscita: dimensione del buffer: 100 sizeof (buffer): 4passaggio del buffer di caricamento alle funzioni e acquisizione della dimensione del buffer

#include <string.h> 
#include <stdio.h> 

void load_buffer(char *buffer); 

int main() 
{ 
    char buffer[100]; 
    printf("buffer size: %d\n", sizeof(buffer)); 
    load_buffer(buffer); 

    return 0; 
} 

void load_buffer(char *buffer) 
{ 
    printf("sizeof(buffer): %d\n", sizeof(buffer)); 
} 
+2

In main() hai dichiarato esplicitamente un array, mentre in load_buffer() hai dichiarato un puntatore. La differenza è che in main() il compilatore sa che il buffer è un array, ma in load_buffer() il compilatore non sa se il buffer proviene da una matrice, o una pace allocata di memoria nell'heap, o una struct o qualsiasi altra cosa . Il compilatore conosce solo l'indirizzo di memoria (quindi un puntatore), quindi sizeof() restituisce la dimensione dell'indirizzo di memoria, che è lungo 4 byte (perché è una macchina a 32 bit, se fosse una macchina a 64 bit, sarebbe 8 byte lunghi). Spero che questo aiuti a capire un po 'di più. – AndaluZ

+0

Invece della funzione sizeof(), utilizzare strlen(), quindi restituisce la dimensione del valore del puntatore. – NandhaKumar

risposta

19

si utilizza la dimensione del puntatore al buffer (4 byte), piuttosto che la dimensione del buffer.

In C, è necessario passare separatamente la dimensione del buffer, che è parte del motivo per cui i sovraccarichi del buffer si verificano in modo semplice e frequente.

void load_buffer(char * buffer, size_t bufSize) 
{  
    ... 
} 
4

Cosa accade, è quando si passa una matrice a una funzione, si passa solo l'indirizzo della matrice di memoria, non la dimensione della matrice. La dimensione di (buffer) in uscita in load_buffer() è la dimensione del puntatore, che è di quattro byte.

Il modo migliore per mantenere la dimensione del buffer nella funzione è quella di modificare la funzione di:

void load_buffer(char *buffer, int length); 

e la chiamata a:

load_buffer(buffer, sizeof(buffer)); 

e quindi utilizzare la lunghezza quando vuoi la dimensione del buffer.

8

dall'OP

void load_buffer(char *buffer) 
{ 
    printf("sizeof(buffer): %d\n", sizeof(buffer)); 
} 

Anche se si può immaginare che load_buffer() viene passato il buffer da refrence, ciò che sta realmente accadendo è si passa un puntatore a char da valore. La matrice reale non viene passato in modo non v'è alcun modo per la funzione load_buffer() conoscere la dimensione dell'array buffer di

Allora, qual è sizeof(buffer) facendo? Sta semplicemente restituendo la dimensione di un puntatore al carattere. Se load_buffer() ha bisogno della dimensione di buffer, deve essere passato in modo sperato.

Oppure si può creare una nuova struct che contiene sia un array di caratteri e la dimensione della matrice, e passare un puntatore a tale struct, invece, in questo modo il buffer e le sue dimensioni sono sempre insieme;)

20

Il le risposte di Mitch Wheat e hhafez sono completamente corrette e pertinenti. Mostrerò alcune informazioni aggiuntive che potrebbero rivelarsi utili a volte.

Si noti che lo stesso accade se si dire al compilatore che si dispone di una serie della giusta dimensione

void load_buffer(char buffer[100]) { 
    /* prints 4 too! */ 
    printf("sizeof(buffer): %d\n", sizeof(buffer)); 
} 

un array come parametro è solo dichiarando un puntatore. Il compilatore lo modifica automaticamente a char *name anche se è stato dichiarato come char name[N].

Se si vuole forzare i chiamanti a passare un array di dimensione 100 solo, è possibile accettare l'indirizzo della matrice (e il tipo di quello), invece:

void load_buffer(char (*buffer)[100]) { 
    /* prints 100 */ 
    printf("sizeof(buffer): %d\n", sizeof(*buffer)); 
} 

E 'un puntatore alla matrice voi avere in main, quindi è necessario dereferenziare nella funzione per ottenere l'array. L'indicizzazione poi viene fatto

buffer[0][N] or (*buffer)[N] 

Nessuno So che sta facendo e sto né farlo io, perché piuttosto complica passaggio dell'argomento. Ma è bello saperlo. È possibile chiamare la funzione come questo allora

load_buffer(&buffer) 

Se si desidera accettare altre dimensioni troppo, vorrei andare con l'opzione di passaggio-N le altre due risposte raccomandano.

+1

+1 Per fare un piccolo sforzo in più – Tom