Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.12.2010, 12:35   #1
JohnnySuperb
Новичок
Джуниор
 
Регистрация: 09.11.2010
Сообщений: 2
Вопрос Очистка динамического массива

Доброго времени суток, форумчане.
У меня возник вопрос. Работаю с переменной типа записи
Код:
test :TTestInfo;
который в свою очередь состоит из строк и чисел и еще массива записей TQuests, в котором также находится массив записей TAnswers.
Код:
  TAnswers = record
    id : integer; // ид ответа на сервере
    text : string; // сам вариант ответа
  end;
  TQuests = record
    id : integer; //ид вопроса
    quest : string; // сам вопрос
    answer : array of TAnswers; // ответы
  end;
  TTestInfo = record
    count:integer; // количество вопросов в тесте
    quests : array of TQuests;// вопросы
  end;
При создании массива ни каких проблем не возникает. Как и при расширении массива.
Использую
Код:
  inc(test.count);
  SetLength(test.quests, test.count);
Теперь мне нужно обнулить весь этот массив. на данный момент использую такой вариант
Код:
  test.count:=0;
  SetLength(test.quests, test.count);
Теперь меня точно интересует - после обнуления массива TQuests таким образом будут ли данные удалены, а память, которую удаленная часть массива занимала освобождена? Или данный кусок памяти так и будет висеть в системе и не будет доступен ни кому?
Хотел посмотреть логику работы Delphi и проверить что делает программа, но в модуле System идет переход на ассемблер, что очень затрудняет дальнейшее изучение этого вопроса.
Знаю, что если используется массив объектов, которые создаются и уничтожаются, то необходимо каждый объект заранее уничтожить, а только потом уже удалять массив. А как обстоят дела с массивом из таких данных?
Мы оптимизируем этот мир.
Все мои мысли можно найти в твиттере - http://twitter.com/johnnysuperb
а все остальное - в моем блоге
JohnnySuperb вне форума Ответить с цитированием
Старый 09.12.2010, 12:48   #2
Kotofff
Участник клуба
 
Аватар для Kotofff
 
Регистрация: 11.01.2009
Сообщений: 1,917
По умолчанию

Код:
test.count:=0;
SetLength(test.quests, test.count);
Обнулит массив, но не высвободит память.
Попробуй FreeMem
"Заряженному танку в дуло не смотрят" @Dekmer in WoT
Kotofff вне форума Ответить с цитированием
Старый 09.12.2010, 13:18   #3
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
так и будет висеть в системе и не будет доступен ни кому?
Никогда не интересовался этим в таких подробностях, но ИМХО именно это утверждение ближе всего к истине.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 09.12.2010, 13:31   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

согласен с вышесказанным.
Память, которую занимал в Вашем Test (типа TTestInfo ) quests: array of TQuests
будет освобождена, но вот память, которую занимал массив
answer : array of TAnswers - скорее всего "повиснет в воздухе"

1) А кто Вам мешает пройти в цикле и обнулить сначала массив answer
а потом уже массив quests ?
примерно так:
Код:
  for i:=Low(test.quests) to High(test.quests) do
     SetLength(test.quests[i].answer, 0);
  SetLength(test.quests, 0);
  test.Count := 0;
2) думаю, что под профайлерами можно посмотреть, особождается ли память. (не исключаю возможности, что дельфийский менеджер памяти достаточно умён, чтобы собрать потерянное...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 09.12.2010, 14:29   #5
Баламут
Баламучу слегка...
Участник клуба
 
Аватар для Баламут
 
Регистрация: 01.11.2006
Сообщений: 1,585
По умолчанию

А вот просто ради интереса

Код:
  t: array of byte;
  .....
  SetLength(t, 10);
  if t <> nil then ShowMessage('Ага!');
  SetLength(t, 0);
  if t = nil then ShowMessage('Упс...');
Думаю это что-то значит...
Баламут вне форума Ответить с цитированием
Старый 09.12.2010, 14:49   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Баламут, а это Вы зачем привели пример?
Речь идёт не об очистке самого динамического массива, а об очистке вложенных структур: если в этом массиве элеметы - тоже динамические массивы.
Вот что тогда с памятью, которую они занимали будет?..

вот, на вашем примере:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var  t: array of array of integer;
begin
  SetLength(t, 2);
  SetLength(t[0], 2); {первый массив Integer на два элемента}
  SetLength(t[1], 4); {второй массив Integer на 4-ре элемента}

  t[0][0] := 100;
  t[0][1] := -1;

  t[1][0] := 1000;
  t[1][1] := 2000;
  t[1][2] := 3000;
  t[1][3] := 4000;

  if t <> nil then ShowMessage('Ага!');
  SetLength(t, 0);
  if t = nil then ShowMessage('Упс...');

end;
вопрос, память, выделенная SetLength(t[0], 2); и SetLength(t[1], 4); будет освобождена или нет?!
я думаю, что нет, не будет!

Последний раз редактировалось Serge_Bliznykov; 09.12.2010 в 14:55.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 09.12.2010, 15:00   #7
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Согласен с постом #4 - циклом по индексам пробегаетесь и все счастливы. Не сложно, всегда так делаю. Только дробите на процедурки - очистка одного элемента, очистка столбца, очистка массива и никаких проблем.
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 09.12.2010, 15:30   #8
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Тогда уж лучше вместо record перейти на class. Красивее будет.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 09.12.2010, 15:40   #9
Баламут
Баламучу слегка...
Участник клуба
 
Аватар для Баламут
 
Регистрация: 01.11.2006
Сообщений: 1,585
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Баламут, а это Вы зачем привели
Ага, проморгал! В этом случае действительно даже не обнулится.

Код:
type
  testArray = array of array of integer;
  TestArray1 = array of integer;
..........
var
  t: TestArray;
  P: Pointer;
begin
  P := nil;
  SetLength(t, 2);
  SetLength(t[0], 2); {первый массив Integer на два элемента}
  SetLength(t[1], 4); {второй массив Integer на 4-ре элемента}

  P:= t[1];

  t[0][0] := 100;
  t[0][1] := -1;

  t[1][0] := 1000;
  t[1][1] := 2000;
  t[1][2] := 3000;
  t[1][3] := 4000;

  if p <> nil then ShowMessage('Ага!');
  SetLength(t, 0);
  ShowMessage(IntToStr(TestArray1(p)[1]));
end;

Последний раз редактировалось Баламут; 09.12.2010 в 15:55.
Баламут вне форума Ответить с цитированием
Старый 09.12.2010, 16:29   #10
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

ну вот, общими усилиями и разобрались!
думаю, что тема закрыта...
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Содержание динамического массива Bish Microsoft Office Excel 6 18.05.2010 15:45
очистка динамического массива BattleMage Общие вопросы C/C++ 1 19.09.2009 09:03
Освобождение динамического массива? VintProg Общие вопросы Delphi 15 28.08.2009 10:41
Сохранение динамического массива Horus92 Помощь студентам 3 07.05.2009 12:36
Удаление динамического массива Сергей089 Общие вопросы C/C++ 3 08.03.2009 13:13