2010-10-07 2 views
1

Может кто-то пожалуйста, объясните мне этот своеобразный выход:выделение памяти для структур

#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-битной машины?

+0

Было бы полезно, если бы кто-то объяснил мне, почему я получил ожидаемый результат на 32-битной машине, а не как таковой на моей 64-битной машине ... – letsc

+0

32-байтовое разделение не связано с требованием ' malloc'. Вы можете видеть, что адреса не выровнены по 32 байт, поэтому для этого не будет большого преимущества. Может быть, мы сможем более точно узнать, какой компилятор/платформа у вас есть. – Potatoswatter

ответ

7

Два вызова 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 и друзей.

+0

Thanx bta .. Это работает .. – letsc

1

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

2

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

0
node *p,q; 

такая же, как:

node *p; 
node q; 

Так

д = (узел *) таНос (SizeOf (узел));

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

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

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

+0

Мне очень жаль. Я, должно быть, съел эту звезду !! – letsc

0

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

0

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

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

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

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