Главная » Просмотр файлов » Керниган и Ритчи - Язык программирования Си

Керниган и Ритчи - Язык программирования Си (793773), страница 44

Файл №793773 Керниган и Ритчи - Язык программирования Си (Керниган и Ритчи - Язык программирования Си) 44 страницаКерниган и Ритчи - Язык программирования Си (793773) страница 442019-04-24СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 44)

Такой алгоритм называется "поиском первого подходящего" в отличие оталгоритма "поиска наилучшего подходящего", который ищет наименьший блок из числа удовлетворяющихзапросу. Если размер блока в точности соответствует требованиям, то такой блок исключается из списка иотдается в пользование. Если размер блока больше, чем требуется, от него отрезается нужная часть — онаотдается пользователю, а ненужная оставляется в списке свободных блоков. Если блока достаточногоразмера не оказалось, то у операционной системы запрашивается еще один большой кусок памяти, которыйприсоединяется к списку свободных блоков.Процедура освобождения сопряжена с прохождением по списку свободных блоков, поскольку нужно найтиподходящее место для освобождаемого блока. Если подлежащий освобождению блок примыкает с какой-тостороны к одному из свободных блоков, то он объединяется с ним в один блок большего размера, чтобы повозможности уменьшить раздробленность (фрагментацию) памяти.

Выполнение проверки, примыкают либлоки друг к другу, не составляет труда, поскольку список свободных блоков всегда упорядочен повозрастанию адресов.Существует проблема, о которой мы уже упоминали в главе 5, состоящая в том, что память, выдаваемаяфункцией malloc, должна быть соответствующим образом выровнена с учетом объектов, которые будут вней храниться. Хотя машины и отличаются друг от друга, но для каждой из них существует тип,предъявляющий самые большие требования на выравнивание, и, если по некоему адресу допускаетсяразмещение объекта этого типа, то по нему можно разместить и объекты всех других типов. На некоторыхмашинах таким самым "требовательным" типом является double, на других это может быть int или long.Свободный блок содержит указатель на следующий блок в списке, свой размер и собственно свободноепространство.

Указатель и размер представляют собой управляющую информацию и образуют такназываемый "заголовок". Чтобы упростить выравнивание, все блоки создаются кратными размеру заголовка,а заголовок соответствующим образом выравнивается. Этого можно достичь, сконструировав объединение,которое будет содержать соответствующую заголовку структуру и самый требовательный в отношениивыравнивания тип. Для конкретности мы выбрали тип long.typedef long Align; /* для выравнивания по границе long */union header { /* заголовок блока: */struct {union header *ptr; /* след. блок в списке свободных */unsigned size; /* размер этого блока */} s;Align x; /* принудительное выравнивание блока */};typedef union header Header;Поле Align нигде не используется; оно необходимо только для того, чтобы каждый заголовок был выровненпо самому "худшему" варианту границы.Затребованное число символов округляется в malloc до целого числа единиц памяти размером в заголовок(именно это число и записывается в поле size (размер) в заголовке); кроме того, в блок входит еще однаединица памяти — сам заголовок.

Указатель, возвращаемый функцией malloc, указывает на свободноепространство, а не на заголовок. Со свободным пространством пользователь может делать что угодно, но,если он будет писать что-либо за его пределами, то, вероятно, список разрушится.Поскольку память, управляемая функцией malloc, не обладает связностью, размеры блоков нельзявычислить по указателям, и поэтому без поля, хранящего размер, нам не обойтись.Для организации начала работы используется переменная base. Если freep есть NULL (как это бывает припервом обращении к malloc), создается "вырожденный" список свободного пространства; он содержитодин блок нулевого размера с указателем на самого себя. Поиск свободного блока подходящего размераначинается с этого указателя (freep), т. е.

с последнего найденного блока; такая стратегия помогаетподдерживать список однородным. Если найденный блок окажется слишком большим, пользователю будетотдана его хвостовая часть; при этом потребуется только уточнить его размер в заголовке найденногосвободного блока. В любом случае возвращаемый пользователю указатель является адресом свободногопространства, размещающегося в блоке непосредственно за заголовком.static Header base; /* пустой список для нач. запуска */static Header *freep = NULL; /* начало в списке своб. блоков *//* malloc: универсальный распределитель памяти */void *malloc(unsigned nbytes){Header *p, *prevp;Header *morecore(unsigned);unsigned nunits;nunits = (nbytes + sizeof (Header) - 1) / sizeof (Header) + 1;if ((prevp = freep) == NULL) { /* списка своб.

памяти еще нет */base.s.ptr = freep = prevp = &base;base.s.size = 0;}for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr) {if (p->s.size >= nunits) { /* достаточно большой */if (p->s.size == nunits) /* точно нужного размера */prevp->s.ptr = p->s.ptr;else { /* отрезаем хвостовую часть */p->s.size -= nunits;p += p->s.size;p->s.size = nunits;}freep = prevp;return (void *)(p+1);}if (p == freep) /* прошли полный цикл по списку */if ((p = morecore(nunits)) == NULL)return NULL; /* больше памяти нет */}}Функция morecore получает память от операционной системы. Детали того, как это делается, могут несовпадать в различных системах. Так как запрос памяти у системы — сравнительно дорогая операция, мы быне хотели для этого каждый раз обращаться к malloc. Поэтому используется функция morecore, котораязапрашивает не менее NALLOC единиц памяти; этот больший кусок памяти будет "нарезаться" потом по меренадобности.

После установки в поле размера соответствующего значения функция morecore вызываетфункцию free и тем самым включает полученный кусок в список свободных областей памяти.#define NALLOC 1024 /* миним. число единиц памяти для запроса *//* morecore: запрашивает у системы дополнительную память */static Header * morecore( unsigned nu){char *cp, *sbrk(int);Header *up;if (nu < NALLOC)nu = NALLOC;ср = sbrk(nu * sizeof(Header));if (cp == (char *) -1) /* больше памяти нет */return NULL;up = (Header *) cp;up->s.size = nu;free((void *)(up+1));return freep;}Системный вызов sbrk(n) в UNIXe возвращает указатель на n байт памяти или -1, если требуемогопространства не оказалось, хотя было бы лучше, если бы в последнем случае он возвращал NULL.

Константу 1 необходимо привести к типу char *, чтобы ее можно было сравнить с возвращаемым значением. Это ещеодин пример того, как операция приведения типа делает функцию относительно независимой от конкретногопредставления указателей на различных машинах. Есть, однако, одна "некорректность", состоящая в том, чтосравниваются указатели на различные блоки, выдаваемые функцией sbrk. Такое сравнение негарантировано стандартом, который позволяет сравнивать указатели лишь в пределах одного и того жемассива. Таким образом, эта версия malloc верна только на тех машинах, в которых допускается сравнениелюбых указателей.В заключение рассмотрим функцию free.

Она просматривает список свободной памяти, начиная с freep,чтобы подыскать место для вставляемого блока. Искомое место может оказаться или между блоками, или вначале списка, или в его конце. В любом случае, если подлежащий освобождению блок примыкает ксоседнему блоку, он объединяется с ним в один блок. О чем еще осталось позаботиться, — так это о том,чтобы указатели указывали в нужные места и размеры блоков были правильными./* free: включает блок в список свободной памяти */void free(void *ap){Header *bp, *p;bp = (Header *)ap -1; /* указатель на заголовок блока */for (p=freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))break; /* освобождаем блок в начале или в конце */if (bp + bp->s.size == p->s.ptr) { /* слить с верхним */bp->s.size += p->s.ptr->s.size; /* соседом */bp->s.ptr = p->s.ptr->s.ptr;} elsebp->s.ptr = p->s.ptr;if (p + p->s.size == bp) { /* слить с нижним соседом */p->s.size += bp->s.size;p->s.ptr = bp->s.ptr;} elsep->s.ptr = bp;freep = p;}Хотя выделение памяти по своей сути — машинно-зависимая проблема, с ней можно справиться, что ииллюстрирует приведенная программа, в которой машинная зависимость упрятана в очень маленькой еечасти.

Что касается проблемы выравнивания, то мы разрешили ее с помощью typedef и union(предполагается, что sbrk дает подходящий в смысле выравнивания указатель). Операции приведения типовпозволяют нам сделать явными преобразования типов и даже справиться с плохо спроектированныминтерфейсом системы. Несмотря на то, что наши рассуждения касались распределения памяти, этот общийподход применим и в других ситуациях.Упражнение 8.6. Стандартная функция calloc(n, size) возвращает указатель на n элементов памятиразмера size, заполненных нулями. Напишите свой вариант callос, пользуясь функцией malloc илимодифицируя последнюю.Упражнение 8.7.

Функция malloc допускает любой размер, никак не проверяя его на правдоподобие; freeпредполагает, что размер освобождаемого блока — правильный. Усовершенствуйте эти программы такимобразом, чтобы они более тщательно контролировали ошибки.Упражнение 8.8. Напишите программу bfree(p, n), освобождающую произвольный блок р, состоящий изn символов, путем включения его в список свободной памяти, поддерживаемый функциями malloc и free.С помощью bfree пользователь должен иметь возможность в любое время добавить в список свободнойпамяти статический или внешний массив.А. Справочное руководствоА 1.

ВведениеДанное руководство описывает язык программирования Си, определенный 31 октября 1989 г. в соответствиис проектом, утвержденным в ANSI в качестве Американского национального стандарта для информационныхсистем: Язык программирования Си, Х3.159-1989 ("American National Standard for Information Systems —Programming Language C, X3.159-1989"). Это описание — лишь один из вариантов предлагаемого стандарта, ане сам стандарт, однако мы специально заботились о том, чтобы сделать его надежным руководством поязыку.Настоящий документ в основном следует общей схеме описания, принятой в стандарте (публикация которогов свою очередь основывалась на первом издании этой книги), однако в организационном плане естьразличия.

Характеристики

Тип файла
PDF-файл
Размер
2,25 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Как Вы думаете, сколько людей до Вас делали точно такое же задание? 99% студентов выполняют точно такие же задания, как и их предшественники год назад. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
7029
Авторов
на СтудИзбе
260
Средний доход
с одного платного файла
Обучение Подробнее