Kazoom
¿Cómo encuentra C el tamaño de una matriz en tiempo de ejecución? ¿Dónde se almacena la información sobre el tamaño o los límites de la matriz?
david z
sizeof(array)
es implementado completamente por el compilador de C. En el momento en que el programa se vincula, lo que parece un sizeof()
llamarte se ha convertido en una constante.
Ejemplo: cuando compila este código C:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
int a[33];
printf("%d\n", sizeof(a));
}
usted obtiene
.file "sz.c"
.section .rodata
.LC0:
.string "%d\n"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $164, %esp
movl $132, 4(%esp)
movl $.LC0, (%esp)
call printf
addl $164, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.1.2 (Gentoo 4.1.2 p1.1)"
.section .note.GNU-stack,"",@progbits
El $132
en el medio está el tamaño de la matriz, 132 = 4 * 33. Observe que no hay call sizeof
instrucción – a diferencia de printf
que es una función real.
-
Esta respuesta es correcta para arreglos de tamaño fijo, pero es incorrecta para matrices de longitud variable que existen desde C99.
– Andreas Wenzel
12 de febrero a las 10:38
Johannes Schaub – litb
sizeof es tiempo de compilación puro en C++ y C antes de C99. A partir de C99 hay matrices de longitud variable:
// returns n + 3
int f(int n) {
char v[n + 3];
// not purely a compile time construct anymore
return sizeof v;
}
Eso evaluará la sizeof
operando, porque n
aún no se conoce en tiempo de compilación. Eso solo se aplica a matrices de longitud variable: otros operandos o tipos todavía hacen que el tamaño de cálculo en tiempo de compilación. En particular, las matrices con dimensiones conocidas en el momento de la compilación aún se manejan como en C++ y C89. En consecuencia, el valor devuelto por sizeof
ya no es una constante de tiempo de compilación (expresión constante). No puede usarlo donde se requiere dicho valor, por ejemplo, al inicializar variables estáticas, a menos que una extensión específica del compilador lo permita (el estándar C permite que una implementación tenga extensiones a lo que trata como constante).
-
Es bueno que mencione los VLA C99. Sin embargo, su respuesta debe enfatizar que incluso en C99, las matrices de tamaño fijo tienen su tamaño calculado en tiempo de compilación; solo los VLA tienen su tamaño calculado en tiempo de ejecución. Y tal vez, como consecuencia, no siempre puedas usar ‘sizeof(array)’ como una constante en C99.
–Jonathan Leffler
23 de marzo de 2009 a las 6:17
-
ok, hora de dormir para mí ahora. más tarde me despertaré y gritaré por todos esos errores tipográficos en mis respuestas: p
– Johannes Schaub – litb
23 de marzo de 2009 a las 6:55
-
+1 para distinguir entre evaluaciones en tiempo de compilación y no compiladas de
sizeof
en C99, pero ¿cómo se calcula realmente la longitud de una matriz de longitud variable? ¿Está almacenado en un descriptor de matriz o algo así?– Kyle Strand
23 de abril de 2013 a las 1:10
S.S
sizeof()
solo funcionará para una matriz de tamaño fijo (que puede ser estática, basada en pilas o en una estructura).
Si lo aplica a una matriz creada con malloc
(o nuevo en C++) siempre obtendrá el tamaño de un puntero.
Y sí, esto se basa en la información de tiempo de compilación.
-
las matrices de tamaño fijo no están necesariamente basadas en pilas. C no tiene operador nuevo.
– ysth
22 de marzo de 2009 a las 23:26
-
Se ha olvidado de C99 VLA – arreglos de longitud variable.
–Jonathan Leffler
23 de marzo de 2009 a las 6:15
-
“Array” tiene un significado bastante específico en el sistema de tipo C. si tienes un formación (no un puntero),
sizeof
debería funcionar, incluso si la matriz está en la memoria asignada conmalloc
(posible mediante el uso del puntero a la matriz en lugar del puntero al elemento).– hyde
1 de febrero de 2022 a las 10:02
sizeof
da el tamaño de la variable, no el tamaño del objeto al que está apuntando (si hay uno). sizeof(arrayVar)
devolverá el tamaño de la matriz en bytes si y solo si arrayVar
se declara en el alcance como una matriz y no como un puntero.
Por ejemplo:
char myArray[10];
char* myPtr = myArray;
printf("%d\n", sizeof(myArray)) // prints 10
printf("%d\n", sizeof(myPtr)); // prints 4 (on a 32-bit machine)
sizeof(Array) se busca en tiempo de compilación, no en tiempo de ejecución. La información no se almacena.
¿Quizás está interesado en implementar la verificación de límites? Si es así, hay varias maneras diferentes de hacerlo.