#include<alloc.h>
#define MAXROW 3
#define MAXCOL 4
main() {
int (*p)[MAXCOL];
p = (int (*)[MAXCOL]) malloc(MAXROW*(sizeof(*p));
}
Сколько байтов выделяется в этом процессе?
р является указателем, поэтому будет занимать sizeof(int(*)[MAXCOL])
в стеке, который может выглядеть пугающим, но это почти всегда так же, как sizeof(void*)
, sizeof(int*)
или любой другой указатель. Очевидно, размеры указателей - это то, что дает приложениям их классификация как 16-, 32-, 64-и т.д. бит, и этот указатель будет соответствующим размером.
Тогда р наведен на некоторое количество памяти, полученной от 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)
Тот факт, что Возвращаемый указатель таНоса является приведением к типу P, Безразлично» t влияет на объем выделенного объема памяти.
Как резко замечает R, отсутствие malloc
прототипа может вызвать компилятор ожидать malloc
вернуть int
, а не на самом деле, вернулся void*
. На практике вероятно, что наименьшие sizeof (int) байты от указателя будут пережить преобразование, и если sizeof (void *) оказался равным sizeof (int), или - еще более слабый, - произойдет куча памяти на адресе, представленном в int
, несмотря на то, что размер указателей больше (т.е. все усеченные биты равны 0) в любом случае, тогда последующее разыменование указателя может работать. Дешевый подключаемый модуль: C++ не будет компилироваться, если не будет показан прототип.
Сказанное, возможно, ваш alloc.h содержит прототип malloc ... У меня нет alloc.h, поэтому я предполагаю, что это нестандартный.
Любая программа также выделяет память для многих других вещей, таких как стек стека, предоставляющий некоторый контекст, в котором может быть вызван main(). Объем памяти, который изменяется в зависимости от компилятора, версия, флаги компилятора, операционной системы и т.д ..
Кто задал этот вопрос интервью, очевидно, никогда не пытался компилировать этот код. – 2010-12-09 06:18:46
Вы уверены? Похоже, что он может скомпилироваться на некоторых барахтовых системах ... – 2010-12-09 06:20:36
Не без дополнительных `)` – 2010-12-09 06:31:19