¿Cómo determina “sizeof” el tamaño de una matriz?

4 minutos de lectura

Avatar de usuario de Kazoom
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?

Avatar de usuario de David Z
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 printfque 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 - avatar de usuario de litb
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

Avatar de usuario de HH
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 con malloc (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.

¿Ha sido útil esta solución?