Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Почему нельзя сделать строкой динамический массив ?


массив ©   (2004-08-22 04:56:00) 

var
 str : string;
 Arr1 : array[1..6000] of Char;
 Arr2 : array of Char;
begin
 str := Arr1;  // Работает.
 str := Arr2;  // Не работает.


Anatoly Podgoretsky   (2004-08-24 17:41:00) [1]

Kerk ©   (24.08.04 15:20) [17]
А как же могло быть иначе, поскольку присвается PChar строке, а PChar никаких управляющих структур не имеет. Поэтому и будет сделана нормальная, рабочая копия, с которой можно безопасно работать, в отличии от string(a), как это продемонстрировал Юрий Зотов ©   (24.08.04 15:08) [16]


Chlavik   (2004-08-24 17:30:00) [2]

SetString ?


Kerk   (2004-08-24 15:20:00) [3]


> Таким образом, в случае S := PChar(A) создается копия тела

Об этом я и говорил. :)


Юрий Зотов   (2004-08-24 15:08:00) [4]

> Kerk ©   (24.08.04 14:04) [15]

Что ж, проверил.


procedure TForm1.FormCreate(Sender: TObject);
begin
 SetLength(A, 4);
 A[0] := 'a';
 A[1] := 'b';
 A[2] := 'c';
 A[3] := #0;
 S1 := PChar(A);
 S2 := String(A);
 A[0] := '0';
 A[1] := '1';
 A[2] := '2';
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 Caption := S1 // Получаем 'abc'
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 Caption := S2 // Получаем '012'
end;


Таким образом, в случае S := PChar(A) создается копия тела (но чтобы все было правильно, массив, естественно, должен завершаться элементом с нулевым символом, как и положено ASCIIZ-строке).

А вот в случае S := String(A) создается копия адреса .


Kerk   (2004-08-24 14:04:00) [5]


> Юрий Зотов ©   (24.08.04 11:55) [13]
> > Kerk ©   (23.08.04 08:55) [12]
>
> Что копия - это понятно. Вот только копия ЧЕГО - адреса
> массива или его тела? В этом вся суть и есть.

Тела. Однозначно. Можешь проверить.
var
 s: string;
 p: PChar; // в исходном куске было приведение типа
begin
 p := 'test';
 s := p;
 p := 'failed';
 ShowMessage(s);
end;


DiamondShark   (2004-08-24 12:57:00) [6]

Нельзя так.
Вызывается @LStrFromPChar.
А она не обращает внимания на длину массива, а только ищет #0 символ.

Трудноуловимые проблемы гарантированы.


Юрий Зотов   (2004-08-24 11:55:00) [7]

> Kerk ©   (23.08.04 08:55) [12]

Что копия - это понятно. Вот только копия ЧЕГО - адреса массива или его тела? В этом вся суть и есть.

IMHO, скопируется адрес. И тогда совершенно реальна такая ситуация - точка выполнения кода выходит из области видимости массива, тот автоматически уничтожается и строка начинает указывать в никуда. После чего при обращении к ней будем иметь Access Violation.


Kerk   (2004-08-23 08:55:00) [8]


> Юрий Зотов ©   (23.08.04 08:40) [11]
> > jack128 ©   (23.08.04 07:42) [10]
>
> И это увеличит счетчик ссылок на Arr2?

Нет. В str будет копия.


Юрий Зотов   (2004-08-23 08:40:00) [9]

> jack128 ©   (23.08.04 07:42) [10]

И это увеличит счетчик ссылок на Arr2?


jack128   (2004-08-23 07:42:00) [10]


> >> А что мешает сделать str := String(Arr2); ?
> > Так работает. Спасибо.
>
> Ох, не уверен я что это работает именно так, как должно
> работать. Имеется в виду управление счетчиком ссылок.
На самом деле это проблема обходится очень просто  str := PChar(Arr2);


Юрий Зотов   (2004-08-23 07:14:00) [11]

> массив   (23.08.04 03:10) [8]

>> А что мешает сделать str := String(Arr2); ?
> Так работает. Спасибо.

Ох, не уверен я что это работает именно так, как должно работать. Имеется в виду управление счетчиком ссылок. Надо бы проверить, иначе есть непохой шанс нарваться на чудеса с памятью.


массив   (2004-08-23 03:10:00) [12]


> Rouse_ ©   (22.08.04 16:25) [3]
> А что мешает сделать str := String(Arr2); ?

Так работает. Спасибо.
А почему тогда str := Arr1;проходило ? В чём отличие ?


TUser   (2004-08-22 19:04:00) [13]


> Такой уж Pascal язык кривой хотя C++ тоже не пряник но возможностей больше

Интересно, к кому относилось ['Лам','Лам','Лам','Лам','Лам','Лам','Лам',...'Лам']?
Наверное к Вирту с Борландом, так?


Юрий Зотов   (2004-08-22 18:19:00) [14]

> TeNY ©   (22.08.04 16:38) [4]

А почему "кривой"?

В каждом языке есть свои правила. При чем тут "кривизна"?


Rouse_   (2004-08-22 17:50:00) [15]

> а потомо что 'Лам'<>['Лам','Лам','Лам','Лам','Лам','Лам','Лам',...'Лам'];
Чего чего?
Это кто ж тебе даст 'Лам' в чаровский массив вставить?

'Лам' = ['Л', 'а', 'м'];

RTFM


TeNY   (2004-08-22 16:38:00) [16]

а потомо что 'Лам'<>['Лам','Лам','Лам','Лам','Лам','Лам','Лам',...'Лам'];
так же и 1<>[1,1,1,1,1,...1]
Без всяких почему!Такой уж Pascal язык кривой хотя C++ тоже не пряник но возможностей больше!


Rouse_   (2004-08-22 16:25:00) [17]

А что мешает сделать str := String(Arr2);?


Юрий Зотов   (2004-08-22 08:08:00) [18]

Почему нельзя? Наверное, потому что этого не позволяет компилятор. Уж так его написали.


массив   (2004-08-22 04:57:00) [19]

Вернее ...
var
 str : string;
 Arr1 : array[1..6000] of Char;
 Arr2 : array of Char;
begin
 str := Arr1;  // Работает.
 SetLength(Arr2, 6000);
 str := Arr2;  // Не работает.


Наверх

Титульная страница Поиск, карта сайта Написать письмо