2010-12-09 3 views
13

Этот вопрос был задан в письменном туре собеседовании:распределения памяти Проблема

#include<alloc.h> 
#define MAXROW 3 
#define MAXCOL 4 

main() 
    { 
    int (*p)[MAXCOL]; 
    p = (int (*)[MAXCOL]) malloc(MAXROW*(sizeof(*p))); 
    } 

Сколько байтов выделяется в этом процессе?

Если быть честным, я не ответил на вопрос. Я не понял задание p.

Может кто-нибудь объяснить мне, что было бы ответом и как это можно было бы вывести?

+1

Кто задал этот вопрос интервью, очевидно, никогда не пытался компилировать этот код. – 2010-12-09 06:18:46

+0

Вы уверены? Похоже, что он может скомпилироваться на некоторых барахтовых системах ... – 2010-12-09 06:20:36

+0

Не без дополнительных `)` – 2010-12-09 06:31:19

ответ

8

Это зависит от платформы.

int (*p)[MAXCOL]; объявляет указатель на массив целых чисел MAXCOL элементов в широком диапазоне (MAXCOL, конечно, 4 в этом случае). Поэтому одним из элементов этого указателя является 4*sizeof(int) на целевой платформе.

Оператор malloc выделяет буфер памяти MAXROW, умноженный на размер типа, содержащегося в P. Поэтому в общем случае выделяются целые числа MAXROW * MAXCOL. Фактическое количество байтов будет зависеть от целевой платформы.

Кроме того, существует, вероятно, дополнительная память, используемая во время выполнения C (как внутренний учет в malloc, так и различные биты инициализации процесса, которые происходят до того, как вызывается main), что также полностью зависит от платформы.

6

sizeof(*p) будет MAXCOL*sizeof(int). Так что полностью MAXROW*MAXCOL*sizeof(int) количество байтов alloctaed.

7

p представляет собой указатель на массив MAXCOL элементов типа int, поэтому sizeof *p (круглые скобки являются излишними) является размер такого массива, т.е. MAXCOL*sizeof(int).

Неприменимо отличное от malloc, уродливое и считается вредным. В этом случае он скрывает серьезную ошибку: из-за отсутствия прототипа malloc предполагается неявным образом возвращать int, что несовместимо с его правильным типом возврата (void *), что приводит к неопределенному поведению.

+0

, если вы добавите к своему ответу, выделенные фактические байты будут лучшим ответом – SiegeX 2010-12-09 06:25:07

3

int (*p)[MAXCOL] == int (*p)[4] == "указатель на массив 4 Int" (см примечание ниже)

sizeof(*p) бы тогда то, что р указывает на, т.е. 4 * sizeof(int). Умножьте это MAXROW и ваш окончательный ответ:

12 * sizeof(int) 

Примечание: Это в отличие от:

int *p[MAXCOL] == int *p[4] == "массив 4 указателя на INT"
Скобки сделать совсем немного разница!

6

Возможно, вы захотите проверить cdecl на помощь при переводе деклараций C на английский язык. В этом случае int (*p)[4]; становится declare p as pointer to array 4 of int.

0

Как насчет нулевых байтов, потому что он даже не будет компилироваться без нестандартного alloc.h.Если вы не можете скомпилировать его, вы не сможете его запустить, и если вы не можете его запустить, он не сможет выделить какую-либо память.

5
#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(). Объем памяти, который изменяется в зависимости от компилятора, версия, флаги компилятора, операционной системы и т.д ..

3

Это должно быть MAXROW * MAXCOL * SizeOf (INT) количество байт

3

мне действительно не нравятся такие вопросы, потому что я думаю, что лучше работать инженером, чтобы экспериментировать, а не предполагать, что вы знаете, что делаете, особенно если есть подозрения, например, что программа работает не так, как ожидалось, или кто-то занимается вопросами трюков.

#include <stdlib.h> 
#include <stdio.h> 
#define MAXROW 3 
#define MAXCOL 4 

main() 
{ 
    int (*p)[MAXCOL]; 
    int bytes = MAXROW * (sizeof(*p)); 
    p = (int (*)[MAXCOL]) malloc(bytes); 
    printf("malloc called for %d bytes\n", bytes); 
} 

На 32 битной системе Linux:

НКУ test.c
./a.out
таНос называется 48 байт

(отредактирован, чтобы удалить оклейки аварии умножения на MAXROW дважды, с ошибкой в ​​размере 144 байт)

1

Выполнение следующих действий на codepad.org:

//#include<alloc.h> 
#define MAXROW 3 
#define MAXCOL 4 

int main() 
{ 
    int (*p)[MAXCOL]; 
    p = (int (*)[MAXCOL]) malloc(MAXROW*(sizeof(*p))); 

    int x = MAXROW*(sizeof(*p)); 
    printf("%d", x); 

    return 0; 
} 

отпечатки 48.

Почему? Потому что MAXROW равно 3, а sizeof(*p) равно 16, поэтому мы получаем 3 * 16.

Почему sizeof(*p) 16? Потому что MAXCOL равно 4, поэтому p является указателем на массив из 4 целых чисел. Каждый int 32 бит = 4 байта. 4 ints в массиве * 4 байта = 16.

Почему sizeof(*p) нет 4? Потому что это размер, на который указывает p, а не размер p. Чтобы быть размером p, он должен был бы быть sizeof(p), который был бы 4, так как p является указателем.

Педантично можно добавить:

  1. Если машина 64 бит (скажем) ответ будет 96.
  2. Поскольку вопрос государств «Сколько байтов, выделяемых в процессе?», Вы необходимо добавить 4 байта для указателя p.
  3. malloc может выделять больше, чем вы просите (но не менее), поэтому на вопрос не может быть дан ответ.
  4. В том же духе, что и в 2, вы можете утверждать, что, поскольку процесс также загружает системные DLL-файлы, такие как DLL C runtime для запуска, он также выделяет пространство для них. Затем вы можете утверждать, что пространство, выделенное dll, которое впрыскивается в процесс другими (не системными) процессами, такими как те, которые были введены Actual Window Manager и его ilk. Но как педантично мы хотим получить?

Но я думаю, что вопрос на самом деле просят 48, с возможностью дополнительного кредита для объяснения 96.

Смежные вопросы