Текущий архив: 2004.09.19;
Скачать: CL | DM;
Вниз
Глюк с массивами Найти похожие ветки
← →
QQ © (2004-09-06 18:26) [0]
type
TMyClass = class
...
FArr : array of String;
...
public
procedure SomeProc(AArr : array of String);
end;
...
procedure TMyClass.SomeProc(AArr : array of String);
begin
FArr := AArr;//ТУТ НЕ КОМПИЛИРУЕТСЯ
end;
причем дажеPointer(FArr) := Pointer(AArr);
не помагает - не приводится!
Вариант:
type
TStringArray = array of String;
TMyClass = class
...
FArr : TStringArray;
...
public
procedure SomeProc(AArr : TStringArray);
end;
...
procedure TMyClass.SomeProc(AArr : TStringArray);
begin
FArr := AArr;//ТУТ работает
end;
это вроде компилируется, но теперь перестает компилироваться
AMyClass = TMyClass.Create;
AMyClass.SomeProc(["s1", "s2", "s3"]);
Вывод:
Дельфи - ущербный языченок!
что делать?
← →
Fay © (2004-09-06 18:28) [1]Ущербность явно имеет место быть. Но причём тут Delphi?
← →
QQ © (2004-09-06 18:29) [2]дело в том, что ссылка и массив - это по-сути
одно и тоже.
но дельфи не дает преобразовать одно в другое.
ищу обходные пути
← →
Anton_K © (2004-09-06 18:31) [3]...ссылка и массив - это по-сути одно и тоже
Не согласен с вами.
← →
QQ © (2004-09-06 18:34) [4]я имел в виду динамический массив
← →
Anton_K © (2004-09-06 18:35) [5]я имел в виду динамический массив
А кто вам сказал, что Delphi не даёт преобразовать их?
← →
QQ © (2004-09-06 18:37) [6]см. мой вопрос
← →
Семен Сорокин © (2004-09-06 18:38) [7]как один из вариантов:
procedure TMyClass.SomeProc(AArr : array of String);
var
_i: integer;
begin
SetLength(FArr, Length(AArr));
for _i := 0 to High(AArr) do
FArr[_i] := AArr[_i]
end;
дело в том, что ссылка и массив - это по-сути
одно и тоже
> AMyClass.SomeProc(["s1", "s2", "s3"]);
а какой должен быть указатель на ["s1", "s2", "s3"]?
← →
QQ © (2004-09-06 18:47) [8]Эффективность, батенька!
эффективность не та!
а указатель на ["s1", "s2", "s3"]
это указатель на (в некотором смысле) константную область памяти, где лежат указатели на строки (опять же констатны)
а AArr : array of String это указатель на такие области!
(см дисассемблер дельфи)
← →
Anton_K © (2004-09-06 18:49) [9]["s1", "s2", "s3"] - это всё передаётся через стек.
← →
Семен Сорокин © (2004-09-06 18:57) [10]Хм. ну раз Вы в этом так уверены, то что Вам стоит сделать вот так:
procedure TMyClass.SomeProc(AArr : array of String);
begin
FArr := @AArr[0];
end;
?
← →
Anton_K © (2004-09-06 19:00) [11]А вы думаете на стек указателей не бывает?
← →
Anton_K © (2004-09-06 19:03) [12]Извените, но кому адресуется сообщение [10]? Мне или QQ?
← →
Семен Сорокин © (2004-09-06 19:04) [13]
> Извените, но кому адресуется сообщение [10]? Мне или QQ?
[10] -> QQ
← →
QQ © (2004-09-06 19:05) [14]>Anton_K © (06.09.04 18:49) [9]
>["s1", "s2", "s3"] - это всё передаётся через стек.
Вы правы. значит, правильно делает, что не дает преобразовать.
← →
Anton_K © (2004-09-06 19:05) [15]Тогда сообщение [11] можно не читать :)
← →
QQ © (2004-09-06 19:40) [16]но тем не менее,
>Семен Сорокин © (06.09.04 18:57) [10]
>Хм. ну раз Вы в этом так уверены, то что Вам стоит сделать вот >так:
>
>procedure TMyClass.SomeProc(AArr : array of String);
>begin
>FArr := @AArr[0];
>end;
>
>?
>
>
>--------------------------------------------------------------->Anton_K © (06.09.04 19:00) [11]
>А вы думаете на стек указателей не бывает?
>
так как адреса строк она запихивает в адрес _подряд_
@AArr[0] это как раз и есть ссылка на массив
только нужно пометить его размерность:FArr := @AArr[0];
SetLength(FArr, Length(AArr));
← →
Anton_K © (2004-09-06 19:43) [17]FArr := @AArr[0];
SetLength(FArr, Length(AArr));
Этим кодом вы создаёте утечку памяти.
← →
Anton_K © (2004-09-06 19:44) [18]И стек при завершении процедуры очищается.
← →
Anton_K © (2004-09-06 19:45) [19]Там нету указателей на строки, сами строки передаются.
← →
Anton_K © (2004-09-06 19:49) [20]Этим кодом вы создаёте утечку памяти.
Нет, я ошибся, утечки не будет. Только после этого FArr не будет равен @AArr[0].
← →
QQ © (2004-09-06 19:56) [21]да, конструкция нестабильная :(
← →
Anton_K © (2004-09-06 19:57) [22]А зачем тебе это вообще нужно?
← →
QQ © (2004-09-06 20:01) [23]хотя нет, ошибаюсь - она копирует массив
причем в момент SetLength ;)
← →
QQ © (2004-09-06 20:02) [24]чтобы как раньше писать вот так:
AMyClass.SomeProc(["s1", "s2", "s3"]);
← →
QQ © (2004-09-06 20:03) [25]GetMem
FillChar
CopyArray
вот она что делает
;)
← →
Anton_K © (2004-09-06 20:12) [26]вот она что делает
Ты уверен?
← →
QQ © (2004-09-06 20:17) [27]угу
DynArraySetLength
в system.pas
но мне везет - могла бы по другой ветке пойти
← →
DiamondShark © (2004-09-07 00:15) [28]
> Вывод:
> Дельфи - ущербный языченок!
> что делать?
Удавиться.
В строчках
FArr : array of String;
и
procedure SomeProc(AArr : array of String);
одинаковая последовательность слов "array of String" означает семантически совершенно различные вещи.
Первое -- динамический массив, второе -- открытый параметр-массив.
Справку читать, ущербный человеченок.
← →
pasha_golub © (2004-09-07 00:40) [29]DiamondShark © (07.09.04 00:15) [28]
Не, Димон, лучше повеситься. ;0)
← →
QQ © (2004-09-07 09:44) [30]
> DiamondShark © (07.09.04 00:15) [28]
>
> > Вывод:
> > Дельфи - ущербный языченок!
> > что делать?
>
> Удавиться.
>
> В строчках
> FArr : array of String;
> и
> procedure SomeProc(AArr : array of String);
>
> одинаковая последовательность слов "array of String" означает
> семантически совершенно различные вещи.
> Первое -- динамический массив, второе -- открытый параметр-массив.
>
> Справку читать, ущербный человеченок.
Это я и сообщении об ошибке видел, молодой человек.
Что хамить-то мы можем, а вот решение предложить - нет?
;)
← →
TUser © (2004-09-07 10:28) [31]Ну понятно - если у озабоченного препода нет времени прояснить себе правила языка Паскаль, то тут понятно D ущербен. Уважаемый, правила в языках разные, и ничего в том страшного нет. Иначе зачем бы создавать такое кол-во различных языков. А то, что вы описали - это не глюк, а фича, причем довольно известная.
← →
QQ © (2004-09-07 10:36) [32]Господа - приношу свои извинения по поводу Delphi -
это была минутная слабость. Я сам пишу на Дельфи, поэтому считаю его удачным для своих целей языком. Просто я некоторое время писал на С++ и не привык к некоторым особенностям Дельфи. (Кстати у Дельфи есть некоторые преимущества перед С++).
Я воспользовался решением Семена Сорокина [10].
← →
Erik1 (2004-09-07 12:18) [33]Вобщето ерундовая проблема, а эфективность даже на 200 элементах этоже милисекнды! Вобщето такое предпологается делать так:
procedure TMyClass.SomeProc(AArr : TStringArray);
begin
FArr := Copy(AArr);
end;
Или так, если поизвращатся охота:
procedure TMyClass.SomeProc(AArr : TStringArray);
Var
Size: Integer;
begin
Size := Length(AArr);
SetLength(FArr, Size);
Move(AArr[0], FArr[0], Size*SizeOf(FArr[0]));
end;
Страницы: 1 вся ветка
Текущий архив: 2004.09.19;
Скачать: CL | DM;
Память: 0.55 MB
Время: 0.032 c