Форум: "Основная";
Текущий архив: 2002.10.03;
Скачать: [xml.tar.bz2];
Вниз
Проблемы с рекурсией и возвратом управления в нужную точку. Найти похожие ветки
← →
Бильврёст (2002-09-24 10:11) [0]Имеею код:
...
procedure MyProc1();
begin
...
MyProc2(param1, param2);
...
end;
procedure MyProc2(param1, param2);
begin
...
while условие do // строка 0
begin
...
MyProc2(param1, param2); // строка 1
... // строка 2
end; { while }
end;
Из примера видно, что я рекурсивно вызываю MyProc2.
Дело в том, что при первом рекурсивном вызыве процедура отрабатывает полностью (несколько раз вызывая сама себя), но закончив цепочку, которая была пораждена первым рекурсивным вызовом возвращает управление на "// строка 2", т.е. процедура MyProc2 продолжает выполняться и дальнейшее выполнение происходит в цикле While, что приводит к ошибке (связынной со спецификой самой процедуры).
Вопрос: как возвратить управление в MyProc1 после того, как цепочка, порождённая первым рекурсивным вызовом окончит работу?
← →
MBo (2002-09-24 10:22) [1]сделать, чтобы условие окончания выполнялось во всех экземплярах MyProc2. Может, передавать для этого var-параметр
← →
Anatoly Podgoretsky (2002-09-24 10:23) [2]Exit
← →
Бильврёст (2002-09-24 10:43) [3]>> MBo © (24.09.02 10:22):
рекурсией пришлось воспользоваться потому что при попытке:
procedure MyProc1();
var
asd: TStringList;
...
begin
asd:= TStringList.Create;
MyProc2(param1, param2, asd);
...
asd.Free; // ошибка
end;
procedure MyProc2(param1, param2: string; DirList: TStringList);
var
...
a: TStringList;
begin
...
a:= TStringList.Create;
...
DirList:= a;
end;
Так вот, в данной ситуации в MyProc2. переменная DirList содержит всё что требуется, но когда управление возвращается в MyProc1, то переменная asd вообще как бы не существует (дебагер показывает нули).
Может тут что-то подскажите?
>>Anatoly Podgoretsky © (24.09.02 10:23):
Это и ежу понятно, что Exit, но вот куда его во вторую процедуру засунуть и каким макаром отследить, что выполняется "проход" в рамках первого рекурсивного вызова - вот это задача 8(
← →
Бильврёст (2002-09-24 11:14) [4]Sorry, естественно:
procedure MyProc2(param1, param2: string; var DirList: TStringList);
← →
qube (2002-09-24 11:16) [5]
> Может тут что-то подскажите?
Вообще-то надо было
DirList.Assign(a);
a.Free;
← →
Бильврёст (2002-09-24 11:23) [6]>>qube © (24.09.02 11:16):
А не подскажете в чём соль?
В данном случае типы полностью совпадают, так почему бы не использовать прямое присвоение (DirList:= a)?
Прошу прощения за возможную неосведомлённость в Паскалевских (очевидных для вас, мастаков) правилах, но я недавно перешёл на Object Pascal - по необхрдимости.
Так что многое от меня ускользает 8(
← →
qube (2002-09-24 11:48) [7]Соль в том, что в случае
DirList := a присваивается указатель, поэтому предыдущее значение указателя asd, созданное в MyProc1 строкой asd := TStringList.Create, теряется. В результает получаем утечку памяти.
← →
Бильврёст (2002-09-24 12:12) [8]>> qube © (24.09.02 11:48):
ЕСТЬ!
Тогда всё понятно, при DirList := a присваевается указатель на переменную "a", а после выхода за область видимости "a" (или её освобождении) область памяти, распределённая под "а" освобождается и при возврате управления в MyProc1 "asd" указывает на "несуществующую" область памяти. Поэтому и нули в дебагере.
Ok. Thanks for help.
Если можно, ещё вопрос.
Если тип будет не TStringList, а, к примеру, Integer, то ведь можно будет просто присвоить DirList:= a; - так? (и DirList, и a - типа Integer).
И вообще, каковы общие правила присвоение указателей в случае передачи параметров по ссылке?
← →
qube (2002-09-24 12:19) [9]1) Насчет области видимости ты опять неправ. Это не С++. Все вручную созданные объекты надо вручную же и удалять (если только их не вставить в контейнер, который сам их прибьет).
2) Integer, естественно, присваивать можно.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.10.03;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.007 c