распределение памяти для структур - PullRequest
1 голос
/ 07 октября 2010

Может кто-нибудь объяснить, пожалуйста, этот специфический вывод:

#include <stdio.h>

typedef struct node
{
  int i;
  struct node *next;
}node;

main()
{
    node *p,*q;
    printf(" %u ",sizeof(node));              // 16
    p = (node *)malloc(sizeof ( node ) ) ;     
    printf(" %p ",p);                    // 0x1cea010
    q = (node *)malloc(sizeof ( node ) ) ; 
    printf("\n %p ",q);                    // 0x1cea030
}

У меня 64-битный процессор.Когда размер показан как 16 байтов, почему 32 байта выделены для узла?Я проверил 32-битную машину.Адреса имели разделение 8 байтов.Без прокладок и прочего.Так является ли разница в 4 байта единственной причиной некоторой проблемы заполнения 64-битной машины ??

Ответы [ 6 ]

7 голосов
/ 07 октября 2010

Два malloc вызова не обязательно возвращают последовательные области памяти.Лучший способ выполнить этот тест:

main()
{
    node *p;
    printf(" %u ",sizeof(node));
    p = (node*)malloc(2 * sizeof (node));     
    printf(" %p \n %p ", &p[0], &p[1]);
    free(p);
}

Выделив массив, вы можете быть уверены, что он находится в спине в памяти.

В зависимости от вашей реализацииmalloc, ваша система может использовать память между p и q для хранения бухгалтерской информации, которая используется realloc, free и друзьями.

2 голосов
/ 07 октября 2010

Адрес, который возвращает malloc (), определяется алгоритмом планирования памяти операционной системы.Вам не гарантируется, что два вызова malloc, следующие друг за другом, получат сегменты памяти друг за другом.При этом ваш код не выделяет 32 байта для p, он выделяет 16. Любые операции записи / чтения, кроме 16 байтов, имеют неопределенное поведение и могут привести к сбою вашей программы.То же относится и к q.

1 голос
/ 07 октября 2010

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

0 голосов
/ 07 октября 2010

malloc () не гарантирует последовательные фрагменты памяти при последовательных вызовах.Он может даже не вернуть две части одной и той же страницы.

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

.malloc () намного, намного умнее, чем можно подумать.Возможно, он пропустил эти 16 байтов на случай, если вы выделите больше структур того же размера или решите перераспределить тот же самый.

0 голосов
/ 07 октября 2010

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

0 голосов
/ 07 октября 2010
node *p,q;

совпадает с:

node *p;
node q;

So

q = (узел *) malloc (sizeof (узел));

Ошибка, поскольку вы присваиваете значение указателя для структуры.

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

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

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