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

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

Pchar(s)^


Страницы:   1 2

Vitec ©   (2008-04-15 19:18:00) 

подскажите пожалуйста, что означает запись: PChar(S)^
s- типа string PChar(S) - преобразуем строку в тип Pchar, а вот что означает значек ^ в конце?


Johnmen   (2008-04-16 19:12:00) [1]


> Семеныч   (16.04.08 17:25) [32]
> Тогда с себя и начни. Умышленно.

Что конкретно мне начать с себя?


Семеныч   (2008-04-16 17:25:00) [2]

> Johnmen ©   (16.04.08 16:54) [31]

Тогда с себя и начни. Умышленно.


Johnmen   (2008-04-16 16:54:00) [3]


> Семеныч   (16.04.08 15:56) [30]
> 2. Вы не ответили на вопрос (последний абзац в [26]). Умышленно?

Да, умышленно. Ибо он для меня риторический.
Если для тебя он иной, то отвечаю:
Наверняка - не знаю, а о предположениях умолчу. Умышленно.


Семеныч   (2008-04-16 15:56:00) [4]

> Johnmen ©   (16.04.08 13:41) [28]

1. Насчет формализованной демагогии - см. [11].

2. Вы не ответили на вопрос (последний абзац в [26]). Умышленно?


Anatoly Podgoretsky   (2008-04-16 15:14:00) [5]

> Leonid Troyanovsky  (16.04.2008 13:26:27)  [27]

И при этом

> PChar(S)^ - это "символ #0, если строка пустая",

РеадОнли память, в сегменте констант, на это часто прокалываются, например с OemToChar(PChar(S), PChar(S))


Johnmen   (2008-04-16 13:41:00) [6]


> Семеныч   (16.04.08 00:27) [22]
> Семеныч   (16.04.08 09:16) [24]
> Семеныч   (16.04.08 10:22) [26]

Кипит наш разум возмущенный (с) ?
Я думаю, к данному моменту уже успокоился...

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

вполне могу возразить:
Но заметьте, что о непустой строке в приведенных выше пресловутых трех пунктах искомой цитаты нет ни одного звука.

Вот такие дела...


Leonid Troyanovsky   (2008-04-16 13:26:00) [7]


> Семеныч   (16.04.08 10:22) [26]

> Насколько помню, заголовок - это все же 8 байт (4 - счетчик
> ссылок и 4 - размер). Ну да ладно, суть не в этом.

Ну, да. Это раньше еще был  allocSiz: Longint, sorry.

> То есть, все три абсолютно верны.

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

Кста потому,  PChar(S)^ - это "символ #0, если строка пустая",
(т.е. бестелесная), а Pointer(s) = nil - перечитай еще раз тезисы 2, 3.

--
Regards, LVT.


Семеныч   (2008-04-16 10:22:00) [8]

> Leonid Troyanovsky ©   (16.04.08 09:30) [25]

>> 1. Что по умолчанию S - это длинная строка.
>> 2. Что S есть указатель на адрес собственного тела.
>> 3. Что тело это заканчивается символом #0.

> Под умолчанием, видимо, подразумевается $H+.

Естественно.

> А вот с телом не совсем точно. Разница проявляется
> именно в пустой строке: указатель есть nil, и никакой
> памяти для нее не распределено

Это тоже азбука. Но заметьте, что о пустойстроке в приведенных выше пресловутых трех пунктах искомой цитаты нет ни одного звука. То есть, все три абсолютно верны.

О пустойстроке я сказал лишь то (см. [2]), что PChar(S)^ - это "символ #0, если строка пустая". И это тожеабсолютно верно.

> Ну, и точнее говорить не на "тело", а на распределенный для строки блок,
> начинающийся с 12 байтового заголовка по отрицательному смещению.

Насколько помню, заголовок - это все же 8 байт (4 - счетчик ссылок и 4 - размер). Ну да ладно, суть не в этом.

Суть в том, что заголовок находится именно по отрицательномусмещению, поэтому самуказатель содержит адрес именно первого символа строки и никакой другой. А это и есть адрес теластроки. Как видим, и здесь все абсолютно точно.

И, наконец: если уж что-то кому-то показалось неточным или неправильным, то надо было, видимо, написать, что именно и почему (как это сделали Вы - а то, что я с Вами не согласился, это уже другой вопрос и это тоже нормально).

Но почему же вместо этого здесь принято бросаться снисходительными и голословными поучениями?


Leonid Troyanovsky   (2008-04-16 09:30:00) [9]


> Семеныч   (16.04.08 00:27) [22]

> 1. Что по умолчанию S - это длинная строка.
> 2. Что S есть указатель на адрес собственного тела.
> 3. Что тело это заканчивается символом #0.

Под умолчанием, видимо, подразумевается $H+.

А вот с телом не совсем точно. Разница проявляется
именно в пустой строке: указатель есть nil, и никакой
памяти для нее не распределено, т.е. он не указывает на #0,
в отличии от PChar('').

Ну, и точнее говорить не на "тело", а на распределенный
для строки блок, начинающийся с 12 байтового заголовка
по отрицательному смещению.

Все это доступно изложено в хелпе, которому и следует,
IMHO, в подобных случаях отсылать страждущих.

--
Regards, LVT.


Семеныч   (2008-04-16 09:16:00) [10]


> Johnmen ©   (15.04.08 20:35) [11]


Дополнение к [22]. Про азбуку (счетчик ссылок и размер в памяти) затрудняться не стоит. Надо сказать, что именно в цитате есть фантазия и почему. Ждем-с.


Vitec   (2008-04-16 09:00:00) [11]

теперь понятно, прочитал заодно про ASCIIZ в википедии и какие с ним обычно бывают ошибки, а также из-за чего возникают Access Violation
всем еще раз спасибо за разъяснения!


Семеныч   (2008-04-16 00:27:00) [12]


> Johnmen ©   (15.04.08 20:35) [11]
>
> > Семеныч   (15.04.08 19:25) [2]
> > По умолчанию S - это длинная строка. То есть, указатель
> > на адрес ее тела (причем тело это заканчивается символом #0).
>
> Не надо фантазий :)


Заявление, потрясающее как своей информативностью, так и своей обоснованностью. Впрочем, здесь такое не редкость, как я успел убедиться. Увы.

Однако же, есть вот такой код

procedure TForm1.FormCreate(Sender: TObject);
var
 Source, Target: string;
 P: Pointer;
 i: integer;
begin
 Source := 'qwerty';
 P := Pointer(Source);
 Target := '';
 for i := 1 to Length(Source) do
 begin
   Target := Target + PChar(P)^;
   P := Pointer(Cardinal(P) + 1);
 end;
 Caption := Target;
 P := Pointer(Cardinal(P) + 1);
 Caption := Format('%s #%d', [Target, Ord(PChar(P)^)]);
end;

Что мы видим из этого кода?
1. Что по умолчанию S - это длинная строка.
2. Что S есть указатель на адрес собственного тела.
3. Что тело это заканчивается символом #0.

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

Уважаемый синештаноноситель! Я, конечно, понимаю, что пояснения и доказательства - дело не царское, но все же: не могли бы Вы все это хоть как-то прокомментировать?

Конечно, хотелось бы комментариев вразумительных. А не в том же духе.


palva   (2008-04-15 22:56:00) [13]


> Хорошо, если,  по нулевому, иногда приводит к записи в реальную
> кучу.

На это моей фантазии не хватило.


tesseract   (2008-04-15 22:50:00) [14]


>  Обычно это приводит к чтению по нулевому адресу - так уж
> устроены строки.


Хорошо, если,  по нулевому, иногда приводит к записи в реальную кучу. И  "плавающий AV" в подарок.


palva   (2008-04-15 22:37:00) [15]


> И все же, из-за чего может возникнуть ошибка доступа к памяти
> при прямом обращении s[1], а не через указатели?

Из-за того что нельзя обращаться к символам пустой строки. Обычно это приводит к чтению по нулевому адресу - так уж устроены строки.

{$APPTYPE CONSOLE}
var
 s: String;
 i: Integer absolute s;
begin
 s := '';
 WriteLn(Integer(PChar(s))); // 4207937
 // Здесь был выделен буфер, и туда скопирована пустая строка с завершающим нулевым байтом.
 WriteLn(Ord(PChar(s)^));    // 0
 WriteLn(i);         // 0
 WriteLn(Ord(s[1])); // попытка чтения по адресу ноль
end.


Игорь Шевченко   (2008-04-15 22:29:00) [16]

function MD5DigestCompare(const Digest1, Digest2: TMD5Digest): Boolean;
begin
 Result := False;
 if Digest1.A <> Digest2.A then
   Exit;
 if Digest1.B <> Digest2.B then
   Exit;
 if Digest1.C <> Digest2.C then
   Exit;
 if Digest1.D <> Digest2.D then
   Exit;
 Result := True;
end;

менять на

function MD5DigestCompare(const Digest1, Digest2: TMD5Digest): Boolean;
begin
 Result := (Digest1.A = Digest2.A) and (Digest1.B = Digest2.B) and (Digest1.C = Digest2.C) and (Digest1.D = Digest2.D);
end;


tesseract   (2008-04-15 22:19:00) [17]


> волшебники, мля...


"И прям,  не волшебники" (С) Жмурки  

Из за специфики работы с памятью. Столько с GlobalAlloc натерпелся....


Palladin   (2008-04-15 21:58:00) [18]

как показывает практика, из-за специфики работы вызываемой функции, а точнее аффторов, ее писавших... которые были на столько чудаками на букву м, что проверяли корректность переданной длинны ASCIIZ... волшебники, мля...


Vitec   (2008-04-15 21:46:00) [19]

Всем спасибо! И все же, из-за чего может возникнуть ошибка доступа к памяти при прямом обращении s[1], а не через указатели?


Игорь Шевченко   (2008-04-15 21:18:00) [20]


> Тогда еще вопрос, что такое плавающий AV?


Сегодня есть, завтра нет.


> почему s[1] может не прокатить?


может и прокатить


Страницы:   1 2

Наверх

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