Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2005.11.13;
Скачать: [xml.tar.bz2];

Вниз

Если функция возвращает динамический массив...   Найти похожие ветки 

 
Jolik ©   (2005-10-20 09:11) [0]

Если функция возвращает динамический массив в качестве результат - создается ли его копия в памяти - или мы получаем ссылку на тот же массив? Т.е. ведет ли себя в этом случае динамический массив как string (я так понял - это близнецы-браться в Дельфи)?
Спасибо!


 
umbra ©   (2005-10-20 09:59) [1]

не совсем понятно, о чем речь. Копия чего создается (или нет) в памяти?


 
TUser ©   (2005-10-20 10:01) [2]

Если ты внутри функции сделал SetLength (result,125), то в этот момент создается его экземпляр в памяти (нужной длины), но он не уничтожается после завершения работы ф-ции. Наоборот, ссылка на этот экземпляр возвращается твоей функцией.


 
begin...end ©   (2005-10-20 10:03) [3]

> Jolik ©   (20.10.05 09:11)

> создается ли его копия в памяти

Нет.

> или мы получаем ссылку на тот же массив?

Да.

Просто на единицу увеличивается счётчик ссылок массива -- поэтому он и не финализируется автоматически перед выходом из подпрограммы.


 
GuAV ©   (2005-10-21 12:29) [4]


> Просто на единицу увеличивается счётчик ссылок массива
> -- поэтому он и не финализируется автоматически перед
> выходом из подпрограммы.


Нет, не поэтому, а потому что не предпринимается никаких попыток финализировать его там.

Функция, возвращающая динамический массив эквивалентна процедуре имеющей дин. массив в качестве var параметра. Т.е. дин массив инициализируется и финализируется в вызывающей, а не в вызываемой подпрограмме.


 
evvcom ©   (2005-10-21 13:00) [5]

И как это в функции результат может инициализироваться в вызывающей программе? Я про случай, когда функция возвращает не ссылку на уже существующий массив (приватное поле или глобальная переменная), а когда делается именно в этой функции SetLength(Result, Value);


 
begin...end ©   (2005-10-24 08:44) [6]

> GuAV ©   (21.10.05 12:29) [4]

> Функция, возвращающая динамический массив эквивалентна процедуре
> имеющей дин. массив в качестве var параметра.

Это понятно, но я говорил про случай, когда внутри функции есть локальная переменная динамического массива, и её значение присваивается Result"у. Посмотри на вопрос -- если имелось в виду не это, то причём тут тогда копия в памяти? По-моему, вопрос был как раз в том, будет ли при таком присваивании копирование массива или нет.

> не предпринимается никаких попыток финализировать его там

Ой.

type
 TStrArray = array of string;

function GetArray: TStrArray;
var
 A: TStrArray;
begin
 SetLength(A, 1);
 A[0] := "abcdef";
 Result := A;
 Dec(PInteger(Cardinal(A) - 8)^)
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 ShowMessage(GetArray[0])
end


Скомпилируй, запусти, удивись :)


 
Anatoly Podgoretsky ©   (2005-10-24 08:54) [7]

Автор не говорит точно об функции, что у него именно и как он работает с этим. Отсюда два толкования. Если строго следовать вопросу, то ни о каких локальных переменных и присвоении их результату и речи быть не должно.


 
Anatoly Podgoretsky ©   (2005-10-24 09:03) [8]

Я к тому,

function Foo: TArrayType;
begin
  BlackBox;
end;


 
GuAV ©   (2005-10-24 22:45) [9]


> Скомпилируй, запусти, удивись :)

Нашел чем удивить :)
Результат не финализируется, финализируется переменная A.

Т.к. обе переменные ссылаются на один и тот же массив, правка счётчика ссылок приводит к тому что финализация предпоследней, а не последней переменной приводит к удалению массива из памяти.

Т.е., для массива как для структуры в памяти счётчик ссылок может менятся, однако массив как переменная (т.е. параметр Result) не финализируется и не инициализируется в вызываемой подпрограмме.

Я подумал, что ты говоришь про переменную, потому, что термин "финализация" применим к именно переменной, а не к структуре в памяти.


 
TButton ©   (2005-10-25 02:55) [10]

по сабжу
если мне нужно, чтоб функция вернула динамический массив
я переделываю её в процедуру
например

type
 tMyArray = array of tSomeThing
...
procedure ReturnValues(var arr: tMyArray);
begin
 SetLength(arr,...
end;

это позволяет создать массив во внешней процедуре (функции)
передать его для наполнения/обработки
и уничтожить не знадумываясь
о том, куда девается память


 
begin...end ©   (2005-10-25 08:24) [11]

> GuAV ©   (24.10.05 22:45) [9]

Ну, как переменная он может быть и не финализируется, но тело массива-результата в примере [6] освобождается. Если вручную не уменьшать счётчик, то не освободится, и именно потому, что счётчик больше нуля. Про такой случай я и говорил в [3].



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2005.11.13;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.48 MB
Время: 0.061 c
14-1129913106
default
2005-10-21 20:45
2005.11.13
Доказательство FAT теоремы


14-1130088231
alexsis
2005-10-23 21:23
2005.11.13
Бесплатный посыл СМС-ок


2-1129787961
Green-Templar
2005-10-20 09:59
2005.11.13
random(2)*2


1-1130242650
DelphiLexx
2005-10-25 16:17
2005.11.13
Группа кнопок


6-1122979880
Readen
2005-08-02 14:51
2005.11.13
IdHTTP: ContentRangeStart и ContentRangeEnd





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский