![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Кто внятно пояснит в чём проблема ?
Kozhanov © (2002-05-31 14:01:00)type
PString = ^String;
procedure TForm1.Button1Click(Sender: TObject);
var
A : array[1..8] of Byte;
begin
FillChar(A, SizeOf(A), 0);
PString(@A[1])^ := "hello, buddy !";
PString(@A[5])^ := "good-bye, buddy !"; //здесь происходит
//крушение если заремить первую строчку ?!!!!!!!!
ShowMessage(PString(@A[1])^);
ShowMessage(PString(@A[5])^);
end;
SPeller (2002-05-31 14:48:00) [41]2Игорь Шевченко © (31.05.02 14:20)
По-моему, внук прав.
PString(@A[1])^ := "hello, buddy !";
Сначала мы указатель на первый элемент массива преобразуем к указателю на строку. Затем пишем начиная с этого указателя текст "hello, buddy !", и последние шесть символов выходят за пределы массива. (Размерность то 8 байт).
А ваша запись
TmyCoolRecord = packed record
A : Byte;
B : PString;
C : PString;
end;
будет работать без проблем. В эту структуру заносится байт и два 4-х байтных указателя на строки. Это равносильно записи
TmyCoolRecord = packed record
A : Byte;
B : Longint;
C : Longint;
end;
Если в чём-то не прав, то поправьте меня.
2Kozhanov © (31.05.02 14:01)
А зачем тебе все эти извратства нужны? Сделай массив строк и пиши в них что захочешь.
MBo (2002-05-31 14:48:00) [42]строка AnsiString есть в самом деле указатель на первый символ, и
ptr:=s
и
ptr:=@s[1]
дадут один результат
(причем перед этим адресом лежит еще счетчик ссылок на эту строку и ее длина)
Kozhanov (2002-05-31 14:47:00) [43]> Внук
Delphi сама выделяет память под String и хранит кол-во
ссылок на String. Если кол-во ссылок становится = 0, то
String сносится из памяти.
Внук (2002-05-31 14:45:00) [44]>>Kozhanov © (31.05.02 14:38)
Я лишь хочу сказать, что неплохо бы выделить память под строки :)
Внук (2002-05-31 14:43:00) [45]>>Игорь Шевченко © (31.05.02 14:20)
IMHO, не будет. Давайте посмотрим:
A : array[1..8] of Byte; - статический массив
PString(@A[5])^ := "good-bye, buddy !";
@A[5] - адрес пятого элемента
PString(@A[5]) - этот адрес трактуется как указатель на AnsiString
PString(@A[5])^ - сама ANSI-строка, то есть указатель на ее первый элемент.
Поскольку явно она не описана, компилятор памятью для неене управляет. Назовем ее S
Где будет лежать S[1]? По смещению a[5]+4, то есть за пределами массива.
Не было под нее выделено памяти, и все тут :)
Kozhanov (2002-05-31 14:38:00) [46]> Игорь Шевченко
Это не изврат !
Я просто проверяю здесь принцип представления данных
в последовательности байт. Этот принцип я буду использовать
потом...
Внук не прав, ведь @A[1] - это указатель(!) на строку
в памяти, а не сама строка. Как считаешь ?
Игорь Шевченко (2002-05-31 14:20:00) [47]Внук © (31.05.02 14:16)
Да ?
type
TmyCoolRecord = packed record
A : Byte;
B : PString;
C : PString;
end;
Не будет работать ?
С уважением,
Игорь Шевченко (2002-05-31 14:17:00) [48]PString(..)^ := String("hello, buddy!")
Зачем такой изврат нужен ?
Внук (2002-05-31 14:16:00) [49]Даже если не комментарить первую строчку, это все равно некорректно.
Начиная с пятого элемента массива пишутся слудеющие данные: длина строки "good-bye, buddy !", сама эта строка, нулевой символ-терминатор. Это больше трех - выход за пределы массива :)