Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

300
Views
¿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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!