2016-09-03 2 views
1

Я иду через этот link и обучения C. Интересная часть на странице:Как объединение предотвращает фрагментацию памяти?

The real purpose of unions is to prevent memory fragmentation by arranging for a standard size for data in the memory. By having a standard data size we can guarantee that any hole left when dynamically allocated memory is freed will always be reusable by another instance of the same type of union.

Я понимаю эту часть с помощью следующего кода:

typedef struct{ 
    char name[100]; 
    int age; 
    int rollno; 
    }student; 

typedef union{ 
    student *studentPtr; 
    char *text; 
    }typeUnion; 

int 
main(int argc, char **argv) 
{ 
    typeUnion union1; 

    //use union1.studentPtr 

    union1.text="Welcome to StackOverflow"; 
    //use union1.text 

    return 0; 
} 

Ну, в приведенном выше коде union1.text повторное использование пространство, ранее использовавшееся union1.studentPtr, не полностью, но все еще использующее.

Теперь часть, которую я не понимаю, когда освобожденное пространство malloc не может быть использовано, что приводит к фрагментации памяти?

редактировать: Переход через комментарии и ответы, обязательно использовать the classic text, добавив, это изменение к столбу предполагая, что это поможет новичкам как я

+8

Примечание: Я категорически не согласен с автором в том, что это «настоящая цель профсоюзов», потому что: а) вам нужно было бы использовать только те союзы, чтобы даже иметь шанс предотвратить фрагментацию (и даже тогда, никоим образом не гарантировано), и б) вы вполне можете тратить массу памяти, что еще хуже, чем фрагментация. – Siguza

+0

Эта ссылка выглядит довольно плохой в целом. Что касается вашего вопроса, я никогда не видел, чтобы профсоюзы использовали для этого. – melpomene

+1

@ Сигуза: На самом деле это гарантировано. Но, как вы писали, вы должны поместить все остальные типы данных в этот единственный «союз». Это полностью противоречит современным принципам кодирования, а именно модуляции. – Olaf

ответ

1

комментарии имеют больше опыта относительно unions в целом.

Что касается Вашего вопроса конкретно, это мое понимание:

  • union выделяет память для наибольшего типа данных в переменной накидной. Так, например, имея short int и long int в союзе будет отложить достаточно памяти для long int2 bytes set aside for long int

  • Представьте вместо союза вы объявляете переменную short int. 1 byte for small int Но тогда необходимо использовать long int. Таким образом, вы используете free на short intfreeing small int memory Затем вы используете malloc для выделения памяти для long int. Это должно быть условной памятью. Итак, теперь ваша память выглядит так. enter image description here С бесплатным байтом в середине используемого блока памяти. Сидит там, ожидая, что вы запросите конкретно 1 байт памяти.

Помимо: Если вы изучаете c я рекомендую the classic text. Он устарел, но мне нравится простота, ясность и стиль в стиле текстовых книг.

+0

Что касается 'классического текста', заказавшего книгу без дальнейших задержек, оцените предложение – Naresh

0

Эта страница неверна, большинство программ просто предполагают, что использование памяти будет в порядке и не обращает на нее никакого внимания.

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

Начните с пустой памятью

_____________________________________________________ 

Тогда связка распределений 32 байт происходит как работает программа.

AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLL________ 

Память выделяется программой проходит весь путь мимо последнего байта «L» распределения, он использует 12 * 8 * 4 = 384 байт.

Теперь программа освобождает любое другое распределение.

AAAA____CCCC____EEEE____GGGG____IIII____KKKK__________ 

Теперь программа действительно только с помощью 6 * 4 * 8 = 192 байт, но операционная система должна сохранять все 352 байт из первого «А» до последнего «K», выделенных на программу. Эти освобожденные промежутки между всеми распределениями являются примером фрагментации памяти.

Теперь программа хочет выделить еще 32-байтовый блок. Это может случиться так:

AAAAMMMMCCCC____EEEE____GGGG____IIII____KKKK_________ 

Новое распределение помещается в одном из промежутков, созданных FreeS, и это хорошо, так как он перерабатывает один из пробелов, поэтому мы тратить меньше места.

Теперь скажите программе, что необходимо выделить 40-байтовый блок. Ни один из недостатков не является достаточно большим, поэтому распределение должно идти в конце, а операционная система должна выделять больше памяти для программы, 352 + 40 = 392 байта. Вся память в этих пробелах теряется. Это вид отходов из-за фрагментации памяти, о которой говорит веб-страница.

Если все распределения были рассчитаны на 40 байт, то можно было бы максимизировать разницу в пробелах.

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