2012-12-25 2 views
5

Я изучаю эту функцию таНос и я мог бы использовать некоторую помощь:таНос и Пустота Указатели

static void *malloc(int size) 
    { 
     void *p; 

     if (size < 0) 
       error("Malloc error"); 
     if (!malloc_ptr) 
       malloc_ptr = free_mem_ptr; 

     malloc_ptr = (malloc_ptr + 3) & ~3;  /* Align */ 

     p = (void *)malloc_ptr; 
     malloc_ptr += size; 

     if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr) 
       error("Out of memory"); 

     malloc_count++; 
     return p; 
} 

Я знаю, что таНос FUNC выделяет память для любого типа, если имеется достаточно памяти, но линии я не понимаю:

p = (void *)malloc_ptr; 
malloc_ptr += size; 

Как он может указывать на любой тип данных? Я просто не могу понять этот указатель void или его местоположение.

Примечание: malloc_ptr является неподписанной долгим

+0

Этот код содержит предположение о том, что указатель на 'беззнаковое long' (т.е.' malloc_ptr') может также указать к любому другому объекту, с точки зрения выравнивания. Это предположение не всегда верно (например, в некоторых системах оно не может указывать на объекты «long double»). –

+0

Код предполагает, что ни один тип не имеет более строгие требования к выравниванию, чем 4-байтовое выравнивание. Код не показывает, как инициализируются 'free_mem_ptr' и' free_mem_end_ptr'. Он не возвращает NULL, когда пространства больше нет. Если функция 'error()' возвращается, то все ад разрывается. –

ответ

5

Причины она возвращает пустой указатель, потому что это не имеет ни малейшего представления, что вы выделяющее место для в malloc вызова. Все, что он знает, это объем запрашиваемого пространства. Это зависит от вас или вашего компилятора, чтобы решить, что заполнит память. Расположение указателя void обычно реализуется как связанный список для обеспечения целостности и знает, какие значения памяти свободны, что удивительно отслеживается в функции free.

+0

, но как он знает, сколько места выделить? как он использует значение размера? Я просто этого не вижу. Например, у меня есть структура с 8 ints 3 символами и 1 float, называемая mystruct, и теоретически она должна выделять пространство памяти для этого, но я просто не могу понять, как – morcillo

+0

@morcillo. В этом случае вы, вероятно, sizeof', который определял бы правильный размер в байтах, необходимый для правильного распределения объявленной вами структуры. – squiguy

+0

Я знаю, что sizeof для этого, но я не понимаю, как это сделать, чтобы выделить пространство в памяти. malloc_ptr имеет размер типа, но как p = (void *) malloc_ptr знает, чтобы выделить 8 байтов, или 2 байта, или 152 байта? это кастинг функции malloc, которая заставляет ее работать? (my_struct *) malloc (sizeof (my_struct)) ?? – morcillo

1

Malloc возвращает указатель на кусок полностью неструктурированной плоской памяти. Указатель (void *) означает, что он не имеет представления о том, на что он указывает (без структуры), просто указывает на некоторую память размера.

Вне вашего вызова в malloc вы можете сообщить своей программе, что этот указатель имеет некоторую структуру. I.e., если у вас есть структура some_struct вы можете сказать: .

Посмотрите, как malloc знает только размер того, что он собирается выделить, но на самом деле не знает его структуры? Ваш вызов в malloc не передает никакой информации о структуре, а просто размер того, сколько памяти выделяется.

Это способ генерации C: malloc возвращает вам определенный объем памяти, и ваша задача - передать его в нужную вам структурированную память.

1

Реализация malloc, поэтому разрешено делать вещи, которые не были бы законными в обычной программе. В частности, он использует преобразование, определяемое реализацией, от unsigned long до void *. Инициализация программы устанавливает malloc_ptr на числовой адрес большого блока нераспределенной памяти. Затем, когда вы запрашиваете выделение, malloc выводит указатель из текущего значения malloc_ptr и увеличивает malloc_ptr на количество байтов, которое вы просили. Таким образом, в следующий раз, когда вы вызовете malloc, он вернет новый указатель.

Речь идет о простейшей возможной реализации malloc. Прежде всего, похоже, что он никогда не использует лишнюю память.

1
p = (void *)malloc_ptr; 

`malloc` returns a void pointer, which indicates that it is a pointer to a region of 
unknown data type. The use of casting is only required in C++ due to the strong type 
system, whereas this is not the case in C. The lack of a specific pointer type 
returned from `malloc` is `type-unsafe` behaviour according to some programmers: 
malloc allocates based on byte count but not on type. 

malloc_ptr += size; 

`C` implicitly casts from and to `void*`, so the cast will be done automatically. In 
`C++` only conversion to void* would be done implicitly, for the other direction an 
explicit cast is required. 

Wiki объяснение о кастинге типа,

`malloc` function returns an untyped pointer type `void *`, which the calling code must 
cast to the appropriate pointer type. Older C specifications required an explicit cast 
to do so, therefore the code `(struct foo *) malloc(sizeof(struct foo))` became the 
accepted practice. However, this practice is discouraged in ANSI C as it can mask a 
failure to include the header file in which `malloc` is defined, resulting in 
downstream errors on machines where the int and pointer types are of different sizes, 
such as the now-ubiquitous x86_64 architecture. A conflict arises in code that is 
required to compile as C++, since the cast is necessary in that language. 
1

Как вы видите, это обе линии,

p = (void *)malloc_ptr; 
malloc_ptr += size; 

здесь вы имеете malloc_ptr типа беззнаковое долго, так что мы типа литья эта переменная к типу void, а затем сохраните его в p. и аналогичным образом второй означает malloc_ptr = malloc_ptr + size;

И эти оба кода предназначены для удобства разработчика, поскольку p является указателем типа void, поэтому в приложении, когда вы используете malloc, тогда вы не знаете, какой тип блока памяти должен быть возвращен функцией, поэтому эта функция всегда возвращает это общий указатель void, чтобы мы могли снова отображать в нашем приложении по требованию.

и та же во втором коде, если вы введите размер в отрицательна, то, что происходит с этим условием

if (free_mem_end_ptr && malloc_ptr >= free_mem_end_ptr) 
error("Out of memory"); 
Смежные вопросы