Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

297
Vistas
¿Puede "sizeof (arr [0])" conducir a un comportamiento indefinido?

Hay un patrón bien conocido para calcular la longitud de la matriz:

 int arr[10]; size_t len = sizeof(arr) / sizeof(arr[0]); assert(len == 10);

Este patrón se aplica a arreglos estáticos y arreglos automáticos de tamaño constante. También se aplica a matrices de longitud variable en C99.

Quiero aplicar una idea similar para calcular el tamaño de la matriz dinámica en bytes:

 size_t known_len = 10; int *ptr = malloc(known_len * sizeof(int)); size_t size = known_len * sizeof(ptr[0]); assert(size == known_len * sizeof(int));

Esto es mejor que known_len * sizeof(int) porque sizeof(ptr[0]) no se refiere al tipo de elemento de matriz real. Por lo tanto, no requiere que el lector del código sepa el tipo.

Sin embargo, no me queda claro si la expresión sizeof(ptr[0]) puede conducir a un comportamiento indefinido. Como se expande:

 sizeof(ptr[0]) -> sizeof(*((ptr) + (0))) -> sizeof(*ptr)

La expresión del resultado es cuestionable en caso de que ptr sea 0 :

 sizeof(*((int*) 0))

Según un estándar C99:

(C99, 6.3.2.3p3): "Una expresión constante de entero con el valor 0 , o una expresión de este tipo convertida en tipo void * , se denomina constante de puntero nulo". Eliminar la referencia a un puntero nulo es un comportamiento indefinido.

(C99, 6.5.3.2.p4) "Si se ha asignado un valor no válido al puntero, el comportamiento del operador unario * no está definido.87)"

87): "Entre los valores no válidos para desreferenciar un puntero mediante el operador unario * se encuentran un puntero nulo, una dirección alineada inapropiadamente para el tipo de objeto al que apunta y la dirección de un objeto después del final de su vida útil".

Pero nunca se especifica si el tamaño de dicha expresión puede conducir a un comportamiento indefinido. De hecho, tal sizeof debe evaluarse en tiempo de compilación.

Mis preguntas son:

  • ¿Se puede usar la expresión sizeof(ptr[0]) en el código cuando se conoce el tipo de ptr y no se conoce el valor de ptr ?
  • ¿Se puede justificar tal uso según el estándar C99? ¿Especificaciones GNU GCC?
over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

La expresión ptr[0] no se evaluará en sizeof(ptr[0]) . El tamaño se determinará simplemente usando el tipo de ptr[0] en tiempo de compilación.

C11: 6.5.3.4:

El operador sizeof produce el tamaño (en bytes) de su operando, que puede ser una expresión o el nombre entre paréntesis de un tipo. El tamaño se determina a partir del tipo del operando . El resultado es un número entero. Si el tipo del operando es un tipo de matriz de longitud variable, se evalúa el operando; de lo contrario, el operando no se evalúa y el resultado es una constante entera.

Eso significa que no hay un comportamiento indefinido.

over 4 years ago · Santiago Trujillo Denunciar

0

Esto no causará un comportamiento indefinido.

Con la excepción de tomar el tamaño de matrices de longitud variable, sizeof es una expresión constante en tiempo de compilación. El compilador procesa la expresión para determinar su tipo, sin producir el código para evaluar la expresión en tiempo de compilación. Por lo tanto, el valor en ptr[0] (que es un puntero no inicializado) no importa en absoluto.

Además, si desea asignar diez números enteros, debe llamar a malloc de esta manera:

 int *ptr = malloc(known_len * sizeof(ptr[0]));

De lo contrario, asigna diez bytes, que es demasiado pequeño para almacenar diez enteros. Tenga en cuenta que en la expresión anterior, ptr no está inicializado en el momento de la llamada, lo que está perfectamente bien para sizeof .

over 4 years ago · Santiago Trujillo Denunciar

0

En el caso general, si me falta algo, la desreferenciación de un puntero nulo en sizeof puede conducir a un comportamiento indefinido. Desde C99, sizeof no es una construcción puramente de tiempo de compilación. El operando de sizeof se evalúa en tiempo de ejecución si el tipo de operando es un VLA.

Considere el siguiente ejemplo

 unsigned n = 10; int (*a)[n] = NULL; // `a` is a pointer to a VLA unsigned i = 0; sizeof a[i++]; // applying `sizeof` to a VLA

De acuerdo con el estándar C99, se supone que se evalúa el argumento de sizeof (es decir, se supone que i se incrementa). Sin embargo, no estoy completamente seguro de que se suponga que la desreferencia de punto nulo en a[0] produzca un comportamiento indefinido aquí.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda