WEB форумы на jedi
[Форум] [Помощь] [Поиск] [Выйти]
Добро пожаловать, [info]User

WEB форумы на jedi [ПОИСК] [Архив до 03.2006]

Тема Распределение кучи К предыдущему сообщению На следующее сообщение Программирование

Отправил Gott в 01:21 20.01.2005[Ответить]
Имеется конструкция вида

...
PType=^TType
TType=record
...
Pt:PType;
...
end;
...


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


Отправил KiaProg в 08:53 20.01.2005[Ответить]
Непонятно


Отправил Gott в 11:39 20.01.2005[Ответить]
Если непонятна цепочка, то под каждую запись типа TType выделяется место в куче, на эту запись указывает указатель типа PType.
Чем-то напоминает определение массива в Си, где значение переменной определяющей массив лишь указатель на первый элемент массива.
Вот и тут, имеется некоторая переменная в программе, допустим Х типа PType, она указывает на первый элемент цепочки. На второй элемент цепочки указывает X.Pt, на третий - X.Pt.Pt и т.д. так вот если я освобожу указатель Х (сделаю ему Dispose(Х) попросту говоря) память выделенная под все остальные элементы цепочки (второй, третий и т.в.т.) останется помеченой как занятая или тоже будет освобождена?


Отправил _TheKoder_ в 16:00 20.01.2005[Ответить]
надо пробегаться по всей цепочке , и удалять каждое звено...


Отправил bargan в 09:54 21.01.2005[Ответить]
Однако есть более оригинальное решение:

1. Пишем у этой структуры деструктор, в котором если указатель на следующий элемент не равен NULL то удаляем данные по этому указателю.
2. В конструкторе этой структуры присваиваем указателю на следующий элемент значение NULL.

тогда чтобы очистить всю очередь, можно будет удалить только верхушку, все остальное удалится само как вы и хотели.

P.S. Вот ведь как сложно вслепую работать, когда среда об утечках не сообщает.


Отправил _TheKoder_ в 10:33 21.01.2005[Ответить]
:-)
ага, а потом человек задаст вопрос, а как удалить, скажем, третий элемент из этого списка ;-)


Отправил bargan в 11:25 21.01.2005[Ответить]
Третий элемент удаляется так:
Находим указатель на 3 элемент, у него указателю на 4 присваиваем NULL (предварительно запомнив его где-нибудь) удаляем 3 элемент. Со второго, указателю следующего присваиваем указатель на 4. Т.е. процедура удаления усложнится всего одним лишним присвоением NULLa.
Но это не типичная операция для очереди, обычно дело обходится удалением с конца, и добавлением в начало, тогда дополнительно делать ничего не придется.
Лучше написать простенький класс, в котором эту очередь оформить двухсвязным списком, тогда удаление с конца будет намного менее затратным для процессора при длинных очередях (не придется пробегать всю очередь).


Отправил _TheKoder_ в 12:21 21.01.2005[Ответить]
------
Но это не типичная операция для очереди, обычно дело обходится удалением с конца, и добавлением в начало, тогда дополнительно делать ничего не придется.
-------

если не важен порядок следования...
[update] - сорри не в тему.


Отправил Gott в 15:50 21.01.2005[Ответить]
Я сейчас решил от нечего делать покумекать над классом, который позволял бы работать с подобным массивом или очередью, да.

2 bargan в самом деле о том чтобы сделать элемент не просто структурой а объектом я тоже думал, однако насколько увеличатся затраты памяти если даже объявить один элемент такого массива не как class а как object (по-моему это только в Паскале есть различие между этими типами, а в Си вроде бы типа object вообще нет), невооруженным глазом будет заметно. А если таких элементов будет много? Поэтому мне показалось, что приятней будет сделать класс, который данную цепочку пробегал бы сам и обнулял каждый элемент, хотя несомненно, предложенный вариант в реализации был бы более удобным. Но приходится выбирать как всегда между скоростью и сложностью.

Вот только еще. Вопрос может показаться глупым, но я раньше не сталкивался ни с чем подобным.
При выделении памяти в куче участок помечается как занятый, после смерти всех указателей на этот участок, он так и остается помеченым как занятый? Т.е. операции x:=nil и dispose(x) равнозначны?


Отправил _TheKoder_ в 16:51 21.01.2005[Ответить]
>Т.е. операции x:=nil и dispose(x) равнозначны?
нет
dispose(x) высвобождает память...
x := nil обнуляет переменную(указатель), с памятью ничего не происходит



Отправил Gott в 17:00 21.01.2005[Ответить]
Спасибо, для меня честно говоря это всегда было небольшой загадкой и всегда хотелось верить что при присваивании переменной значения nil менеджер кучи память освобождает (это о пресловутом сборе мусора в Си, кто-то вроде говорил о наличии его, не берусь утвержать), но горькая правда жизни...


Отправил bargan в 18:19 21.01.2005[Ответить]
> однако насколько увеличатся затраты памяти
В вашем случае на 0, т.к. объект класса не содержащего виртуальных функций, занимает столько места, сколько необходимо для хранения всех его переменных. В случае наличия виртуальных функций дополнительное место требуется только для хранения v-table (таблица виртуальных функций)


Отправил Gott в 14:50 22.01.2005[Ответить]
В вашем случае на 0
Интересно, никогда над этим не задумывался, сегодня же сравню по скорости выполнения и по занимаемой памяти. Хотя все вполне логично, все равно меня терзают смутные сомнения, что где-то тут собака порылась.