2009-03-04 11 views
11

He configurado el búfer al tamaño 100. Muestro el búfer en la función principal donde se declara el búfer. Sin embargo, cuando paso el búfer a la función y obtengo el tamaño de '4', , pensaba que debería ser 100, ya que ese es el tamaño del buffer que I creó en main. salida: tamaño de búfer: 100 sizeof (buffer): 4pasando el búfer char a las funciones y obteniendo el tamaño del búfer

#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

En main() declaró explícitamente una matriz, mientras que en load_buffer() declaró un puntero. La diferencia es que, en main() el compilador sabe que el búfer es una matriz, pero en load_buffer() el compilador no sabe si el búfer es de una matriz, o una paz de memoria asignada en el montón, o una estructura o lo que sea . El compilador solo conoce la dirección de memoria (por lo tanto, un puntero), así sizeof() devuelve el tamaño de la dirección de memoria, que tiene 4 bytes de longitud (porque es una máquina de 32 bits, si fuera una máquina de 64 bits, sería 8 bytes de largo). Espero que esto ayude a entender un poco más. – AndaluZ

+0

En lugar de la función sizeof(), use strlen(), luego devuelve el tamaño del valor del puntero. – NandhaKumar

Respuesta

19

está utilizando el tamaño del puntero a la memoria intermedia (4 bytes), en lugar del tamaño de la memoria intermedia.

En C, tiene que pasar el tamaño del búfer por separado, lo que es parte de la razón por la que los desbordamientos del búfer ocurren de manera fácil y frecuente.

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

¿Qué sucede, es cuando se pasa una matriz a una función, sólo se pasa la dirección de la matriz en la memoria, no el tamaño de la matriz. ¿Qué sizeof (buffer) está produciendo en load_buffer() es el tamaño del puntero, que es de cuatro bytes.

La mejor manera de mantener el tamaño del búfer en la función es cambiar la función a:

void load_buffer(char *buffer, int length); 

y la llamada a:

load_buffer(buffer, sizeof(buffer)); 

y luego usar la longitud siempre que lo desee el tamaño del buffer

8

Desde el PO

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

A pesar de que se puede imaginar que load_buffer() se pasa el buffer por refrence, lo que realmente está sucediendo es que está pasando un puntero a char por valor. La matriz real no se pasa, por lo que no hay forma de que la función load_buffer() conozca el tamaño de la matriz de almacenamiento intermedio

¿Qué hace sizeof(buffer)? Simplemente devuelve el tamaño de un puntero a char. Si load_buffer() necesita el tamaño de buffer, debe pasarse específicamente.

O puede crear una nueva estructura que contiene una matriz de caracteres y el tamaño de la matriz, y pasar un puntero a la estructura en su lugar, de esa manera el tampón y su tamaño son siempre juntos;)

20

El las respuestas de Mitch Wheat y hhafez son completamente correctas y directas. Voy a mostrar información adicional que a veces puede ser útil.

Tenga en cuenta que lo mismo sucede si le dice al compilador que tiene una matriz del tamaño adecuado

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

Una serie como parámetro se acaba de declarar un puntero. El compilador lo cambia automáticamente a char *name, incluso si se declaró como char name[N].

Si desea forzar las personas que llaman para pasar una matriz de tamaño 100 solamente, se puede aceptar la dirección de la matriz (y el tipo de eso) en su lugar:

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

Es un puntero a la matriz que tener en main, por lo que necesita dereference en la función para obtener la matriz. La indexación se realiza entonces por

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

Nadie que yo conozca que está haciendo y yo no lo estoy haciendo a mí mismo, porque en vez complica paso del argumento. Pero es bueno saber sobre eso. Puede llamar a la función como esta a continuación

load_buffer(&buffer) 

Si desea aceptar otros tamaños también, me gustaría ir con la opción passing-N las otras dos respuestas recomiendan.

+1

+1 Por hacer un pequeño esfuerzo adicional – Tom

Cuestiones relacionadas