2010-06-01 14 views
26

Ejemplo completo:¿Por qué una matriz C tiene un valor de sizeof() incorrecto cuando se pasa a una función?

#include <stdio.h> 

void test(int arr[]) { 
    int arrSize = (int)(sizeof(arr)/sizeof(arr[0])); 
    printf("%d\n", arrSize); // 2 (wrong?!) 
} 

int main (int argc, const char * argv[]) { 
    int point[3] = {50, 30, 12}; 

    int arrSize = (int)(sizeof(point)/sizeof(point[0])); 
    printf("%d\n", arrSize); // 3 (correct :-)) 

    test(point); 

    return 0; 
} 

antes de pasarlo a una función, sizeof me da el valor correcto. Hacer exactamente lo mismo en la misma matriz en la función produce resultados extraños. Falta un elemento. ¿Por qué?

Respuesta

37

Cuando pasa una matriz a una función en C, la matriz se desintegra en un puntero a su primer elemento. Cuando usa sizeof en el parámetro, está tomando el tamaño del puntero, no la matriz en sí.

Si necesita la función de conocer el tamaño de la matriz, debe pasarlo como un parámetro independiente:

void test(int arr[], size_t elems) { 
    /* ... */ 
} 

int main(int argc, const char * argv[]) { 
    int point[3] = {50, 30, 12}; 
    /* ... */ 
    test(point, sizeof(point)/sizeof(point[0])); 
    /* ... */ 
} 

También tenga en cuenta que, por una razón similar (tomando el sizeof un puntero), la sizeof(point)/sizeof(point[0]) truco no funciona para una matriz dinámicamente asignada, solo una matriz asignada en la pila.

2

Porque, cuando se pasa, solo se pasa el puntero a la matriz.

Su pregunta también se atiende en The C Programming FAQ. Pregunta 6.21.

+0

Para ser quisquilloso: Es un puntero al primer elemento de la matriz que se pasa. Mismo valor, pero diferente tipo. – alk

0

Porque sizeof() NO te dice el tamaño de una matriz en C. Hace algo completamente diferente.

sizeof C++ reference

+0

Si ha mirado de cerca el ejemplo, verá que no uso sizeof para obtener directamente el número de elementos en la matriz ... sizeof debería decirme cuánta memoria está reservada para la matriz ... y en realidad eso debería coincidir con la cantidad de elementos que hay allí, cuando se conoce el tamaño de un elemento. ¿O me estoy perdiendo algo? – dontWatchMyProfile

+0

Soy corregido. Pero como se indicó anteriormente, tenga cuidado con los punteros.Te dicen su tamaño, no el tamaño del tipo que estás apuntando. – PeterK

12

Debido matriz es decayed a un puntero cuando pasa como argumento de la función, por lo sizeof le da 4 y 8 para las plataformas de 32 y 64 bits respectivamente.

6

Además, es importante comprender que sizeof se evalúa en tiempo de compilación. Como ese es el caso, no tiene sentido esperar resultados diferentes en test() dependiendo de lo que se transfirió. El cálculo de sizeof se realizó cuando se compiló la función.

2

Porque en C, C++ y Objective-C, las funciones no pueden tener realmente parámetros de matriz. Solo pueden tener parámetros que se parecen a los parámetros de matriz, pero no son. En su ejemplo,

void test(int arr[]) 

el compilador ve "no es un parámetro que se parece a una matriz de int", y que sustituye al parámetro con un "puntero a int". Por lo que la función que usted escribió es absolutamente, al cien por cien, idéntica a

void test (int* arr) 

Por lo tanto, dentro de la función sizeof (arr) le dará el tamaño de un "puntero a int".

Cuestiones relacionadas