punteros funcion ejemplos arreglos apuntadores c arrays pointers sizeof

funcion - sizeof en c



¿Cómo encontrar el ''sizeof''(un puntero que apunta a una matriz)? (13)

En primer lugar, aquí hay un código:

int main() { int days[] = {1,2,3,4,5}; int *ptr = days; printf("%u/n", sizeof(days)); printf("%u/n", sizeof(ptr)); return 0; }

¿Hay alguna manera de averiguar el tamaño de la matriz a la que ptr (en lugar de simplemente dar su tamaño, que es de cuatro bytes en un sistema de 32 bits)?


Como han indicado todas las respuestas correctas, no puede obtener esta información solo del valor del puntero decaído de la matriz. Si el puntero decaído es el argumento recibido por la función, entonces el tamaño de la matriz de origen debe proporcionarse de alguna otra manera para que la función llegue a conocer ese tamaño.

Aquí hay una sugerencia diferente de lo que se ha proporcionado hasta ahora, que funcionará: en su lugar, pase un puntero a la matriz. Esta sugerencia es similar a las sugerencias de estilo de C ++, excepto que C no admite plantillas o referencias:

#define ARRAY_SZ 10 void foo (int (*arr)[ARRAY_SZ]) { printf("%u/n", (unsigned)sizeof(*arr)/sizeof(**arr)); }

Pero, esta sugerencia es un poco tonta para su problema, ya que la función está definida para saber exactamente el tamaño de la matriz que se pasa (por lo tanto, no hay necesidad de usar sizeof en absoluto en la matriz). Lo que sí hace, sin embargo, es ofrecer algún tipo de seguridad. Le prohibirá pasar una matriz de un tamaño no deseado.

int x[20]; int y[10]; foo(&x); /* error */ foo(&y); /* ok */

Si se supone que la función puede operar en cualquier tamaño de matriz, entonces deberá proporcionar el tamaño a la función como información adicional.


Hay una solución limpia con plantillas de C ++, sin usar sizeof () . La siguiente función getSize () devuelve el tamaño de cualquier matriz estática:

#include <cstddef> template<typename T, size_t SIZE> size_t getSize(T (&)[SIZE]) { return SIZE; }

Aquí hay un ejemplo con una estructura foo_t :

#include <cstddef> template<typename T, size_t SIZE> size_t getSize(T (&)[SIZE]) { return SIZE; } struct foo_t { int ball; }; int main() { foo_t foos3[] = {{1},{2},{3}}; foo_t foos5[] = {{1},{2},{3},{4},{5}}; printf("%u/n", getSize(foos3)); printf("%u/n", getSize(foos5)); return 0; }

Salida:

3 5


Hola, en las cadenas, hay un carácter ''/0'' al final, de modo que uno puede obtener el tamaño de una cadena con funciones como strlen El problema con una matriz de enteros, por ejemplo, es que u no puede usar ningún valor como valor final, por lo que uno Una posible solución es abordar la matriz y utilizar como valor final el puntero NULL

/* http://.com/questions/492384/how-to-find-the-sizeof-a-pointer-pointing-to-an-array */ #include <stdio.h> /* the following function will produce the warning: * ‘sizeof’ on array function parameter ‘a’ will * return size of ‘int *’ [-Wsizeof-array-argument] */ void foo( int a[] ) { printf( "%lu/n", sizeof a ); } /* so we have to implement something else one possible * idea is to use the NULL pointer as a control value * the same way ''/0'' is used in strings but this way * the pointer passed to a function should address pointers * so the actual implementation of an array type will * be a pointer to pointer */ typedef char * type_t; /* line 18 */ typedef type_t ** array_t; /* * -- -- * -**-**- * -$$$$$- * -999- * -^- * - */ int main( void ) { array_t initialize( int, ... ); /* initialize an array with four values "foo", "bar", "baz", "foobar" * if one wants to use integers rather than strings than in the typedef * declaration at line 18 the char * type should be changed with int * and in the format used for printing the array values * at line 45 and 51 "%s" should be changed with "%i" */ array_t array = initialize( 4, "foo", "bar", "baz", "foobar" ); int size( array_t ); /* print array size */ printf( "size %i:/n", size( array )); void aprint( char *, array_t ); /* print array values */ aprint( "%s/n", array ); /* line 45 */ type_t getval( array_t, int ); /* print an indexed value */ int i = 2; type_t val = getval( array, i ); printf( "%i: %s/n", i, val ); /* line 51 */ void delete( array_t ); /* free some space */ delete( array ); return 0; } /* the output of the program should be: * size 4: * foo * bar * baz * foobar * 2: baz */ #include <stdarg.h> #include <stdlib.h> array_t initialize( int n, ... ) { /* here we store the array values */ type_t *v = (type_t *) malloc( sizeof( type_t ) * n ); va_list ap; va_start( ap, n ); int j; for ( j = 0; j < n; j++ ) v[j] = va_arg( ap, type_t ); va_end( ap ); /* the actual array will hold the addresses of those * values plus a NULL pointer */ array_t a = (array_t) malloc( sizeof( type_t *) * ( n + 1 )); a[n] = NULL; for ( j = 0; j < n; j++ ) a[j] = v + j; return a; } int size( array_t a ) { int n = 0; while ( *a++ != NULL ) n++; return n; } void aprint( char *fmt, array_t a ) { while ( *a != NULL ) printf( fmt, **a++ ); } type_t getval( array_t a, int i ) { return *a[i]; } void delete( array_t a ) { free( *a ); free( a ); } /* край */


La respuesta es no."

Lo que hacen los programadores de C es almacenar el tamaño de la matriz en algún lugar. Puede ser parte de una estructura, o el programador puede engañar un poco y malloc () más memoria que la solicitada para almacenar un valor de longitud antes del inicio de la matriz.


Mi solución a este problema es guardar la longitud de la matriz en una matriz de estructura como una metainformación sobre la matriz.

#include <stdio.h> #include <stdlib.h> struct Array { int length; double *array; }; typedef struct Array Array; Array* NewArray(int length) { /* Allocate the memory for the struct Array */ Array *newArray = (Array*) malloc(sizeof(Array)); /* Insert only non-negative length''s*/ newArray->length = (length > 0) ? length : 0; newArray->array = (double*) malloc(length*sizeof(double)); return newArray; } void SetArray(Array *structure,int length,double* array) { structure->length = length; structure->array = array; } void PrintArray(Array *structure) { if(structure->length > 0) { int i; printf("length: %d/n", structure->length); for (i = 0; i < structure->length; i++) printf("%g/n", structure->array[i]); } else printf("Empty Array. Length 0/n"); } int main() { int i; Array *negativeTest, *days = NewArray(5); double moreDays[] = {1,2,3,4,5,6,7,8,9,10}; for (i = 0; i < days->length; i++) days->array[i] = i+1; PrintArray(days); SetArray(days,10,moreDays); PrintArray(days); negativeTest = NewArray(-5); PrintArray(negativeTest); return 0; }

Pero tiene que preocuparse por establecer la longitud correcta de la matriz que desea almacenar, porque no hay manera de verificar esta longitud, como explicaron masivamente nuestros amigos.


No hay solución mágica. C no es un lenguaje reflexivo. Los objetos no saben automáticamente lo que son.

Pero tienes muchas opciones:

  1. Obviamente, añade un parámetro.
  2. Envuelva la llamada en una macro y agregue automáticamente un parámetro
  3. Utiliza un objeto más complejo. Defina una estructura que contenga la matriz dinámica y también el tamaño de la matriz. Luego, pase la dirección de la estructura.

No, no puede usar sizeof(ptr) para encontrar el tamaño del array ptr que apunta ptr .

Aunque asignar memoria adicional (más que el tamaño de la matriz) será útil si desea almacenar la longitud en espacio adicional.


No, no puedes. El compilador no sabe a qué apunta el puntero. Hay trucos, como terminar la matriz con un valor conocido fuera de banda y luego contar el tamaño hasta ese valor, pero eso no es usar sizeof.

Otro truco es el mencionado por Zan , que es guardar el tamaño en algún lugar. Por ejemplo, si está asignando dinámicamente la matriz, asigne un bloque un int más grande que el que necesita, oculte el tamaño en la primera int y devuelva ptr + 1 como puntero a la matriz. Cuando necesite el tamaño, disminuya el puntero y eche un vistazo al valor oculto. Solo recuerda liberar todo el bloque desde el principio, y no solo la matriz.


Para arreglos dinámicos ( malloc o C ++ nuevo ), necesita almacenar el tamaño del arreglo como lo mencionaron otros o tal vez construir una estructura de administrador de arreglos que maneje agregar, eliminar, contar, etc. Desafortunadamente, C no hace esto tan bien como C ++, ya que básicamente tiene que compilarlo para cada tipo de matriz diferente que está almacenando, lo cual es incómodo si tiene varios tipos de matrices que necesita administrar.

Para las matrices estáticas, como la de su ejemplo, hay una macro común utilizada para obtener el tamaño, pero no se recomienda ya que no comprueba si el parámetro es realmente una matriz estática. Sin embargo, la macro se utiliza en código real, por ejemplo, en los encabezados del kernel de Linux, aunque puede ser ligeramente diferente a la siguiente:

#if !defined(ARRAY_SIZE) #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0])) #endif int main() { int days[] = {1,2,3,4,5}; int *ptr = days; printf("%u/n", ARRAY_SIZE(days)); printf("%u/n", sizeof(ptr)); return 0; }

Puedes buscar en Google por razones para desconfiar de macros como esta. Ten cuidado.

Si es posible, el estándar de C ++, como el vector, es mucho más seguro y fácil de usar.


Para este ejemplo específico, sí, hay, SI utiliza typedefs (ver más abajo). Por supuesto, si lo haces de esta manera, puedes usar SIZEOF_DAYS, ya que sabes a qué apunta el puntero.

Si tiene un puntero (nulo *), como lo devuelve malloc () o similar, entonces, no, no hay forma de determinar a qué estructura de datos apunta el puntero y, por lo tanto, no hay manera de determinar su tamaño.

#include <stdio.h> #define NUM_DAYS 5 typedef int days_t[ NUM_DAYS ]; #define SIZEOF_DAYS ( sizeof( days_t ) ) int main() { days_t days; days_t *ptr = &days; printf( "SIZEOF_DAYS: %u/n", SIZEOF_DAYS ); printf( "sizeof(days): %u/n", sizeof(days) ); printf( "sizeof(*ptr): %u/n", sizeof(*ptr) ); printf( "sizeof(ptr): %u/n", sizeof(ptr) ); return 0; }

Salida:

SIZEOF_DAYS: 20 sizeof(days): 20 sizeof(*ptr): 20 sizeof(ptr): 4


Puedes hacer algo como esto:

int days[] = { /*length:*/5, /*values:*/ 1,2,3,4,5 }; int *ptr = days + 1; printf("array length: %u/n", ptr[-1]); return 0;


#define array_size 10 struct { int16 size; int16 array[array_size]; int16 property1[(array_size/16)+1] int16 property2[(array_size/16)+1] } array1 = {array_size, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; #undef array_size

array_size está pasando a la variable de tamaño :

#define array_size 30 struct { int16 size; int16 array[array_size]; int16 property1[(array_size/16)+1] int16 property2[(array_size/16)+1] } array2 = {array_size}; #undef array_size

El uso es:

void main() { int16 size = array1.size; for (int i=0; i!=size; i++) { array1.array[i] *= 2; } }


int main() { int days[] = {1,2,3,4,5}; int *ptr = days; printf("%u/n", sizeof(days)); printf("%u/n", sizeof(ptr)); return 0; }

El tamaño de los días [] es 20, que no corresponde al tamaño de los elementos * del tipo de datos. Mientras que el tamaño del puntero es 4 no importa a lo que apunta. Porque un puntero apunta a otro elemento almacenando su dirección.