2009-03-04 7 views
11

J'ai mis le tampon à la taille 100. Je montre le tampon dans la fonction principale où le tampon est déclaré. Cependant, quand je passe le tampon à la fonction et obtiens le sizeof '4', je pensais qu'il devrait être 100, car c'est la taille du tampon que j'ai créé dans . sortie: taille de mémoire tampon: 100 sizeof (tampon): 4en passant le tampon char aux fonctions et en obtenant la taille du tampon

#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

Dans main() vous avez explicitement déclaré un tableau, tandis que dans load_buffer() vous avez déclaré un pointeur. La différence est, dans main() le compilateur sait que le buffer est un tableau, mais dans load_buffer() le compilateur ne sait pas si le buffer provient d'un tableau, ou une paix allouée dans le tas, ou une structure ou autre . Le compilateur ne connaît que l'adresse mémoire (donc un pointeur), donc sizeof() renvoie la taille de l'adresse mémoire, qui est longue de 4 octets (parce que c'est une machine 32 bits, si c'était une machine 64 bits, octets longs). J'espère que cela aide à comprendre un peu plus. – AndaluZ

+0

Au lieu de la fonction sizeof(), utilisez strlen(), puis il retourne la taille de la valeur du pointeur. – NandhaKumar

Répondre

19

vous utilisez la taille du pointeur vers la mémoire tampon (4 octets), plutôt que la taille de la mémoire tampon. En C, vous devez passer séparément la taille de la mémoire tampon, ce qui explique en partie pourquoi les dépassements de mémoire tampon sont si fréquents et si fréquents.

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

Qu'est-ce qui se passe, est lorsque vous passez un tableau à une fonction, vous passez uniquement l'adresse du tableau dans la mémoire, pas la taille du tableau. Ce que sizeof (buffer) sort dans load_buffer() est la taille du pointeur, qui est de quatre octets.

La meilleure façon de garder la taille de la mémoire tampon dans la fonction est de changer la fonction:

void load_buffer(char *buffer, int length); 

et l'appel à:

load_buffer(buffer, sizeof(buffer)); 

puis utiliser la longueur chaque fois que vous voulez la taille du tampon.

8

De l'OP

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

Même si vous pouvez imaginer que load_buffer() est passé par la buffer refrence, ce qui se passe réellement est que vous passez un pointeur vers char par valeur. Le tableau réel n'est pas passé, donc il n'y a aucun moyen pour la fonction load_buffer() de connaître la taille du tableau tampon

Alors, qu'est-ce que sizeof(buffer)? Il retourne simplement la taille d'un pointeur sur char. Si load_buffer() a besoin de la taille de buffer il doit être passé speratly.

Ou vous pouvez créer une nouvelle structure qui contient à la fois un tableau de caractères et la taille du tableau, et passer un pointeur vers cette struct à la place, de cette façon le tampon et sa taille sont toujours ensemble;)

20

Le Les réponses de Mitch Wheat et de Hhafez sont tout à fait exactes et pertinentes. Je vais montrer quelques informations supplémentaires qui peuvent s'avérer utiles parfois.

Notez que la même chose se produit si vous dites au compilateur que vous avez un tableau de la bonne taille

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

Un tableau en tant que paramètre est un pointeur juste déclarer. Le compilateur passe automatiquement à char *name même s'il a été déclaré char name[N].

Si vous voulez forcer les appelants à passer un tableau de taille 100 seulement, vous pouvez accepter l'adresse du tableau (et le type de cela) à la place:

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

Il est un pointeur vers le tableau vous avoir en main, donc vous devez déréférencer dans la fonction pour obtenir le tableau. L'indexation se fait alors par

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

Je ne connais personne fait cela et je ne le faire moi-même, parce qu'elle complique plutôt le passage de l'argument. Mais c'est bon à savoir à ce sujet. Vous pouvez appeler la fonction comme celui-ci alors

load_buffer(&buffer) 

Si vous souhaitez accepter d'autres tailles aussi, je voudrais aller avec l'option passant-N les deux autres réponses recommandent.

+1

+1 Pour faire un petit effort supplémentaire – Tom

Questions connexes