Как работает sizeof (Array) - PullRequest
       6

Как работает sizeof (Array)

47 голосов
/ 23 марта 2009

Как можно найти во время выполнения размер массива? где хранится информация о размере или границах массива?

Ответы [ 5 ]

60 голосов
/ 23 марта 2009

sizeof(array) полностью реализован компилятором C. К тому времени, когда программа свяжется, то, что похоже на sizeof() вызов к вам, будет преобразовано в константу.

Пример: когда вы компилируете этот код C:

#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
    int a[33];
    printf("%d\n", sizeof(a));
}

вы получите

    .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

$132 в середине - это размер массива, 132 = 4 * 33. Обратите внимание, что нет инструкции call sizeof - в отличие от printf, которая является реальной функцией.

17 голосов
/ 23 марта 2009

sizeof - это чистое время компиляции в C ++ и C до C99. Начиная с C99 существуют массивы переменной длины:

// returns n + 3
int f(int n) {
    char v[n + 3];

    // not purely a compile time construct anymore
    return sizeof v;
}

Это оценивает операнд sizeof, потому что n еще не известен во время компиляции. То, что только применяется к массивам переменной длины: другие операнды или типы по-прежнему делают размер вычислений во время компиляции. В частности, массивы с измерениями, известными во время компиляции, все еще обрабатываются как в C ++ и C89. Как следствие, значение, возвращаемое sizeof, больше не является константой времени компиляции (константным выражением). Вы не можете использовать его там, где требуется такое значение - например, при инициализации статических переменных, если только это не разрешено специфическим расширением компилятора (стандарт C позволяет реализации иметь расширения к тому, что он рассматривает как константу).

8 голосов
/ 23 марта 2009

sizeof() будет работать только для массива фиксированного размера (который может быть статическим, на основе стека или в структуре).

Если применить его к массиву, созданному с помощью malloc (или нового в C ++), вы всегда получите размер указателя.

И да, это основано на информации времени компиляции.

6 голосов
/ 23 марта 2009

sizeof дает размер переменной, а не размер объекта, на который вы указываете (если он есть). sizeof(arrayVar) вернет размер массива в байтах, если и только если arrayVar объявлено в области видимости как массив, а не как указатель.

Например:

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)
2 голосов
/ 23 марта 2009

sizeof (Array) ищется во время компиляции, а не во время выполнения. Информация не сохраняется.

Возможно, вы заинтересованы во внедрении проверки границ? Если так, то есть несколько способов сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...