|
Программирование >> Решение нетривиальных задач
... if ( MAX == x ) ... В этой идее есть достоинства, но я нахожу, что такой код труднее читается. 73. Помещайте код, динамически распределяющий и освобождающий память, в одном и том же месте Утечки памяти - выделенную память забыли освободить - являются большой проблемой в приложениях, продолжительность работы которых не ограничена: серверах баз данных, торговых автоматах, операционных системах и так далее. Имеется множество способов для того, чтобы отслеживать эту проблему. Многие программы, например, модифицируют функцию malloc() для создания списка выделенных областей памяти, который может просматриваться функцией free() для проверки задействованных указателей. Вы также можете доработать заголовочный файл, необходимый для сопровождения списка выделенных областей памяти, путем помещения туда информации о том, откуда было произведено выделение памяти. (Передайте LINE и FILE в свою отладочную версию malloc() ). Список выделенных областей памяти должен быть пуст при завершении работы программы. Если он не пуст, то вы можете его просмотреть и, по крайней мере, разобраться, где была выделена эта память. Отслеживание - это хорошо, но предупреждение лучше. Если есть возможность, то вы должны размещать free() в той же функции, где сделан соответствующий вызов malloc() . Например, используйте это: void user( void ) пользователь p = malloc( size ); producer( p ); изготовитель consumer( p ); потребитель free( p ); вместо этого: void *producer( ) void *p = malloc( size ); ... return p; void consumer( void *p ) ... 10 free object( some class *object ) 11 { 12 Вместо того, чтобы передать память из-под объекта 13 функции free(), свяжите ее с началом списка 14 высвобожденных элементов. 15 object->next = free list; free( p ); void user( void ) void *p = producer(); consumer( p ); Несмотря на это, вы не сможете всегда делать подобное на Си. Например, предыдущие правила о неинициализированных переменных относятся и к памяти, выделенной malloc(). Лучше сделать так: some object *p = allocate and init(); Не возвращает значения, если памяти недостаточно. чем так: some object *p = malloc( sizeof(some object) ); if( !p ) fatal error( Недостаточно памяти! ) init(); В Си++ эта проблема решается при помощи конструкторов. 74. Динамическая память - дорогое удовольствие Следующей основной проблемой при использовании malloc()/free() (или new/delete) является время, требуемое для управления памятью; оно может быть значительным. Я однажды сократил время выполнения на 50% путем замены многочисленных вызовов malloc() и free() на другую стратегию. Например, если у вас есть очень активно используемая структура из одинаковых объектов, то вы можете использовать нечто подобное коду из листинга 4 для управления членами структуры данных. Листинг 4. Управление собственным списком высвобожденных элементов free list = object; 17 } 18 --------------------------------------------------------19 free all objects( ) 20 { 21 Высвободить все объекты в список высвобожденных 22 элементов. Сортировка этих объектов по базовому адресу 23 перед началом цикла улучшит скорость работы по 24 освобождению, но я не делаю здесь этого. (Для 25 сортировки связанных списков превосходно подходит 26 алгоритм Quicksort). 28 some object *current; 2 9 while( free list ) 30 { 31 current = free list; 32 free list = current->next; 33 free( current ); 34 } 35 } 36 --------------------------------------------------------37 some class *new object( ) 38 { 39 Если в списке высвобожденных элементов имеется объект, 40 то используйте его. Размещайте объект посредством 41 malloc(),только если список высвобожденных объектов 42 пуст. 43 some class *object; 44 if ( free list ) 45 { 46 object = free list; передайте память для объекта 47 free list = object->next; 48 } 49 else 50 { 51 Вы можете улучшить производительность еще более,если 52 будете размещать объекты в памяти по 100, а не по 1 53 за раз, но это усложнит функцию free all objects(). 55 object = malloc( sizeof(some class) ); 56 } 57 58 if( object ) 59 поместите здесь инициализирующий код 61 return object; 62 } 75. Тестовые подпрограммы не должны быть интерактивными Мне часто показывают тестовые программы, имеющие усовершенствованный интерактивный интерфейс пользователя. Это не
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |