Текущий архив: 2008.05.18;
Скачать: CL | DM;
ВнизPchar(s)^ Найти похожие ветки
← →
Vitec (2008-04-15 19:18) [0]подскажите пожалуйста, что означает запись: PChar(S)^
s- типа string PChar(S) - преобразуем строку в тип Pchar, а вот что означает значек ^ в конце?
← →
Palladin © (2008-04-15 19:22) [1]разименование указателя, бежим изучать основы паскаля...
← →
Семеныч (2008-04-15 19:25) [2]По умолчанию S - это длинная строка. То есть, указатель на адрес ее тела (причем тело это заканчивается символом #0).
Тип PChar - это указатель на символ.
Значит, PChar(S) - это адрес первого символа строки S.
А PChar(S)^ - это сам первый символ строки (или символ #0, если строка пустая).
← →
Anatoly Podgoretsky © (2008-04-15 19:53) [3]> Vitec (15.04.2008 19:18:00) [0]
А зачем такие глупости делать, для работы со строками нет нужды приводить к PChar и далее делать разименование.
← →
Vitec (2008-04-15 20:09) [4]Palladin,
угу, надо почитать, с указателями не подружился еще, без них обходился
Семеныч,
спасибо за разъяснения
Anatoly Podgoretsky
Пытаюсь разобраться в md5function MD5String(const S: string): TMD5Digest;
begin
Result := MD5Buffer(PChar(S)^, Length(S));
end;
нужно для функции MD5Buffer, которая используется для обработки данных разных типов
← →
Anatoly Podgoretsky © (2008-04-15 20:21) [5]> Vitec (15.04.2008 20:09:04) [4]
Это какой то бессмысленный код, вот если убрать каре, то будет рабочим.
← →
Vitec (2008-04-15 20:27) [6]код как-раз прекрасно работает:
http://www.delphiworld.narod.ru/base/md5.html
в нем и разбираюсь.
← →
Palladin © (2008-04-15 20:29) [7]
> Anatoly Podgoretsky © (15.04.08 20:21) [5]
это очень хитрый код... у меня доступа нет по http куда нибудь кроме delphimaster"a, но могу предположить, что объявление выглядит так
MD5Buffer(Var p; ...);
← →
tesseract © (2008-04-15 20:30) [8]
> код как-раз прекрасно работает:
Это поймёт тебя компилятор или нет. Delphi иногда такое прощает.
← →
tesseract © (2008-04-15 20:33) [9]
> это очень хитрый код... у меня доступа нет по http куда
> нибудь кроме delphimaster"a, но могу предположить, что объявление
> выглядит так
function MD5Buffer(const Buffer; Size: Integer): TMD5Digest;
т.е разименование тут роли сыграть не должно :-).
← →
Palladin © (2008-04-15 20:34) [10]
> tesseract © (15.04.08 20:33) [9]
я так и предполагал const или var, очень даже должно, вместо нарыва на AV при s[1], мы хитро на уровне compiler magic приводим string к pchar и спокойно разименовываем
← →
Johnmen © (2008-04-15 20:35) [11]
> Семеныч (15.04.08 19:25) [2]
> По умолчанию S - это длинная строка. То есть, указатель
> на адрес ее тела (причем тело это заканчивается символом
> #0).
Не надо фантазий :)
← →
tesseract © (2008-04-15 20:42) [12]
> мы хитро на уровне compiler magic приводим string к pchar
> и спокойно разименовываем
Такие привычки надо ликвидировать, но тут сработает без проблем. "Плавающий AV " - плата за умность компилятора.
← →
Vitec (2008-04-15 21:01) [13]Тогда еще вопрос, что такое плавающий AV? и почему s[1] может не прокатить?
P.s. про указатели уже почти дочитал :)
← →
Игорь Шевченко © (2008-04-15 21:18) [14]
> Тогда еще вопрос, что такое плавающий AV?
Сегодня есть, завтра нет.
> почему s[1] может не прокатить?
может и прокатить
← →
Vitec (2008-04-15 21:46) [15]Всем спасибо! И все же, из-за чего может возникнуть ошибка доступа к памяти при прямом обращении s[1], а не через указатели?
← →
Palladin © (2008-04-15 21:58) [16]как показывает практика, из-за специфики работы вызываемой функции, а точнее аффторов, ее писавших... которые были на столько чудаками на букву м, что проверяли корректность переданной длинны ASCIIZ... волшебники, мля...
← →
tesseract © (2008-04-15 22:19) [17]
> волшебники, мля...
"И прям, не волшебники" (С) Жмурки
Из за специфики работы с памятью. Столько с GlobalAlloc натерпелся....
← →
Игорь Шевченко © (2008-04-15 22:29) [18]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;
← →
palva © (2008-04-15 22:37) [19]
> И все же, из-за чего может возникнуть ошибка доступа к памяти
> при прямом обращении 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.
← →
tesseract © (2008-04-15 22:50) [20]
> Обычно это приводит к чтению по нулевому адресу - так уж
> устроены строки.
Хорошо, если, по нулевому, иногда приводит к записи в реальную кучу. И "плавающий AV" в подарок.
← →
palva © (2008-04-15 22:56) [21]
> Хорошо, если, по нулевому, иногда приводит к записи в реальную
> кучу.
На это моей фантазии не хватило.
← →
Семеныч (2008-04-16 00:27) [22]
> 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.
Таким образом, код полностью подтверждает каждое слово в той самой моей фразе, которую Вы процитировали и почему-то посчитали фантазией. Не снисходя до пояснений и уж тем более, доказательств.
Уважаемый синештаноноситель! Я, конечно, понимаю, что пояснения и доказательства - дело не царское, но все же: не могли бы Вы все это хоть как-то прокомментировать?
Конечно, хотелось бы комментариев вразумительных. А не в том же духе.
← →
Vitec (2008-04-16 09:00) [23]теперь понятно, прочитал заодно про ASCIIZ в википедии и какие с ним обычно бывают ошибки, а также из-за чего возникают Access Violation
всем еще раз спасибо за разъяснения!
← →
Семеныч (2008-04-16 09:16) [24]
> Johnmen © (15.04.08 20:35) [11]
Дополнение к [22]. Про азбуку (счетчик ссылок и размер в памяти) затрудняться не стоит. Надо сказать, что именно в цитате есть фантазия и почему. Ждем-с.
← →
Leonid Troyanovsky © (2008-04-16 09:30) [25]
> Семеныч (16.04.08 00:27) [22]
> 1. Что по умолчанию S - это длинная строка.
> 2. Что S есть указатель на адрес собственного тела.
> 3. Что тело это заканчивается символом #0.
Под умолчанием, видимо, подразумевается $H+.
А вот с телом не совсем точно. Разница проявляется
именно в пустой строке: указатель есть nil, и никакой
памяти для нее не распределено, т.е. он не указывает на #0,
в отличии от PChar("").
Ну, и точнее говорить не на "тело", а на распределенный
для строки блок, начинающийся с 12 байтового заголовка
по отрицательному смещению.
Все это доступно изложено в хелпе, которому и следует,
IMHO, в подобных случаях отсылать страждущих.
--
Regards, LVT.
← →
Семеныч (2008-04-16 10:22) [26]> 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 13:26) [27]
> Семеныч (16.04.08 10:22) [26]
> Насколько помню, заголовок - это все же 8 байт (4 - счетчик
> ссылок и 4 - размер). Ну да ладно, суть не в этом.
Ну, да. Это раньше еще был allocSiz: Longint, sorry.
> То есть, все три абсолютно верны.
Я ж показал, что не абсолютно.
Т.е., для полноты не хватает именно пустой строки.
Кста потому, PChar(S)^ - это "символ #0, если строка пустая",
(т.е. бестелесная), а Pointer(s) = nil - перечитай еще раз тезисы 2, 3.
--
Regards, LVT.
← →
Johnmen © (2008-04-16 13:41) [28]
> Семеныч (16.04.08 00:27) [22]
> Семеныч (16.04.08 09:16) [24]
> Семеныч (16.04.08 10:22) [26]
Кипит наш разум возмущенный (с) ?
Я думаю, к данному моменту уже успокоился...
Так вот.
Если ты начинаешь применять отформализованную демагогию и понятие абсолюта, то я, в этом же духе, на
> Но заметьте, что о пустой строке в приведенных выше пресловутых трех
> пунктах искомой цитаты нет ни одного звука.
вполне могу возразить:
Но заметьте, что о непустой строке в приведенных выше пресловутых трех пунктах искомой цитаты нет ни одного звука.
Вот такие дела...
← →
Anatoly Podgoretsky © (2008-04-16 15:14) [29]> Leonid Troyanovsky (16.04.2008 13:26:27) [27]
И при этом
> PChar(S)^ - это "символ #0, если строка пустая",
РеадОнли память, в сегменте констант, на это часто прокалываются, например с OemToChar(PChar(S), PChar(S))
← →
Семеныч (2008-04-16 15:56) [30]> Johnmen © (16.04.08 13:41) [28]
1. Насчет формализованной демагогии - см. [11].
2. Вы не ответили на вопрос (последний абзац в [26]). Умышленно?
← →
Johnmen © (2008-04-16 16:54) [31]
> Семеныч (16.04.08 15:56) [30]
> 2. Вы не ответили на вопрос (последний абзац в [26]). Умышленно?
Да, умышленно. Ибо он для меня риторический.
Если для тебя он иной, то отвечаю:
Наверняка - не знаю, а о предположениях умолчу. Умышленно.
← →
Семеныч (2008-04-16 17:25) [32]> Johnmen © (16.04.08 16:54) [31]
Тогда с себя и начни. Умышленно.
← →
Johnmen © (2008-04-16 19:12) [33]
> Семеныч (16.04.08 17:25) [32]
> Тогда с себя и начни. Умышленно.
Что конкретно мне начать с себя?
Страницы: 1 вся ветка
Текущий архив: 2008.05.18;
Скачать: CL | DM;
Память: 0.54 MB
Время: 0.048 c