#include<alloc.h>
#define MAXROW 3
#define MAXCOL 4
main() {
int (*p)[MAXCOL];
p = (int (*)[MAXCOL]) malloc(MAXROW*(sizeof(*p));
}
Сколько байтов выделено в процессе?
p - это указатель, поэтому он будет занимать sizeof(int(*)[MAXCOL])
в стеке, что может показаться пугающим, но оно почти всегда совпадает с sizeof(void*)
, sizeof(int*)
или любым другим указателем. Очевидно, что размеры указателей дают приложениям их классификацию как 16-, 32-, 64-и т. Д. биты, и этот указатель будет иметь соответствующий размер.
Тогда p указывает на некоторую память, полученную из malloc
...
malloc( MAXROW * sizeof(*p) )
sizeof(*p)
- это размер массива int
, на который указывает p
, а именно sizeof(int) * MAXCOL
, поэтому мы получаем
malloc( MAXROW * (sizeof(int) * MAXCOL) )
запрашивается из кучи. Для наглядности, если мы примем общий 32-битный размер int
, мы смотрим на 48 байтов. Фактическое использование может быть округлено до того, что чувствуют подпрограммы кучи (подпрограммы кучи часто использовали фиксированные размеры «сегментов» для ускорения своих операций).
Чтобы подтвердить это ожидание, просто замените функцию регистрации на malloc()
:
#include <stdio.h>
#define MAXROW 3
#define MAXCOL 4
void* our_malloc(size_t n)
{
printf("malloc(%ld)\n", n);
return 0;
}
int main()
{
int (*p)[MAXCOL];
p = (int (*)[MAXCOL]) our_malloc(MAXROW*(sizeof(*p)));
}
Вывод на мою коробку Linux:
malloc(48)
Тот факт, что возвращаемый указатель malloc приведен к типу p, не влияет на объем выделенной памяти.
Как резко заметил R, отсутствие прототипа malloc
заставило бы компилятор ожидать, что malloc
вернет int
, а не фактически возвращенное void*
. На практике, вероятно, что наименьший размер (int) байтов из указателя переживет преобразование, и если sizeof (void *) окажется равным sizeof (int) или, что еще более незначительно, то начнется кучи памяти по адресу, представленному в int
, несмотря на то, что размер указателей больше (т. е. все усеченные биты были равны нулю в любом случае), тогда последующая разыменование указателя может сработать. Дешевый плагин: C ++ не скомпилируется, пока не увидит прототип.
Тем не менее, возможно, ваш alloc.h содержит прототип malloc ... У меня нет alloc.h, поэтому я думаю, что он нестандартный.
Любая программа также выделяет память для многих других вещей, таких как стековый фрейм, обеспечивающий некоторый контекст, в котором может быть вызван main (). Объем памяти для этого зависит от компилятора, версии, флагов компилятора, операционной системы и т. Д.