Текущий архив: 2003.04.24;
Скачать: CL | DM;
ВнизПроблема с PChar Найти похожие ветки
← →
Anatoly Podgoretsky (2003-04-14 12:01) [40]Так не оказывается, по определению он должен указывать на строку ASCIIZ, но может указывать на что угодно, это уже в твоих руках.
В Дельфи 1 PChar был именно указателем на Char, теперь на строку.
← →
default (2003-04-14 12:49) [41]Unit1.pas.29: Str := "12345"
0044CD48 mov eax,$0044cd54
0044cd4d mov [Str],eax
0044CD54 31 32 33 34 35 00 00 00 12345...
что не ясно?
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Str: PChar;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Str := "12345";
if @Str <> @Str[0] then Caption := "Адрес самой переменной Str не равен " +
" адресу первого байта строки";
Char((@Str^)^) := "!";
Button1.Caption := Str // Button1.Caption = "!2345"
end;
end.
глянь этот код
может наведёт на какие мыслишки...
← →
default (2003-04-14 13:22) [42]unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Str1: PChar;
Str2: String;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Str1 := "12395";
Str2 := "56616479";
Char(Pointer(LongWord(@Str1[0]) + 3)^) :=
Char(Pointer(LongWord(@Str2[1]) + 5)^);
Caption := Str1; // Form1.Caption = "12345"
end;
end.
вот ещё тебе показательный пример
Всё наверно уже понял?Или в процессе?
← →
Fantasist. (2003-04-14 18:37) [43]
> В Дельфи 1 PChar был именно указателем на Char, теперь на
> строку
Хмы. Когда это PChar стал указателем на строку? Что вы понимаете под строкой вообще (будем считать, что вы не имели ввиду паскалевский тип string)? Строка, как я привык считать, это последовательность байт, когда мы говорим об указателе на такую последовательность, мы обычно подразумеваем указатель на первый ее элемент, то есть указатель указывает только на один элемент (в нашем случае, на один символ), а никак не на весь сегмент целиком.
Вообще, по моему мнению, PChar во многих случаях вещь удобная (чаще при парсинге), мне, лично, нравиться и незачем задаваться вопросом "зачем?".
> default © (14.04.03 12:49)
А ты зря так выпендриваешься - не самый умный.
← →
jack128 (2003-04-14 18:50) [44]default © (14.04.03 13:22)
> var
> Form1: TForm1;
> Str1: PChar;
> Str2: String;
>
> implementation
>
> {$R *.dfm}
>
> procedure TForm1.Button1Click(Sender: TObject);
> begin
>
> Str1 := "12395";
> Str2 := "56616479";
>
> Char(Pointer(LongWord(@ Str1[0]) + 3)^) :=
> Char(Pointer(LongWord(@Str2[1]) + 5)^);
> Caption := Str1; // Form1.Caption = "12345"
>
> end;
>
> end.
Как и ожидалось AV!
Giemgo
> Оказывается PChar не указывает на данные, он указывает на
> область памяти, где записан адрес этих данных
Не знаю как вы к такому выводу пришли, но это не так!!
Pchar - это указатель на символ, не больше, но и не меньше...
То что Борланд разрешил такое присваивание (p := "my string", где p : pchar) не о чем не говорит.
Насчет разницы между ссылкой и указателем , это в книги...Растекаться мысью по древу времени нет..
← →
Giemgo (2003-04-14 18:56) [45]Вы, наверное, не совсем поняли мое сообщение Giemgo (14.04.03 11:38)
1) Вы не могли бы мне объяснить разницу между указателем и ссылкой ?
2) Проблема вот в чем. Попробую описать подробнее. Тем более после экспериментов я потерял все нити, которые раньше нащупал. Давайте, я напишу что делаю, чтобы каждый мог повторить. И напишу чего мне кажется странным.
Допустим, есть такой код:
procedure TForm1.Button1Click(Sender: TObject);
var P:Pchar;
begin
p:="Hello";
showmessage(p); //Здесь брекпоинт
end;
Значит, нажимаю на кнопку - программа останавливается. Вызываю Watch List. Ввожу туда P и @P
p: "Hello" - как бы все ок
@p: $12F5BC
Перехожу по адресу $12F5BC. Для этого вызываю CPU Window и в нижнем левом поле жму Goto Address.
По этому адресу расположен байт (и следующие за ним три байта):
FC F6 12 00 - что вовсе не похоже на Hello
То есть, @p указывает на FC. Хотя я думал, что он должен указывать на байт, где записана первая буква слова, то еть на "H"
Ну и как тогда дельфи узнает, что p это "Hello" ? (в watch list"е). Да и showmessage выводит все правильно.
Если перейти по адесу 00 12 F6 FC то там тоже Hello нету.
Сама строчка распологается по адресу: $00452128
Это я узнал из ассемблерного кода:
Unit1.pas.29: p:="Hello";
004520F0 BB28214500 mov ebx, $00452128<---
Unit1.pas.30: showmessage(p);
004520F5 8D45FC lea eax,[ebp-$04]
Ну и как он узнает, что P это Hello, если @p указывает на какую-то FC F6 12 00
если кто что понял и может прояснить - буду безмерно благодарен
тааак. После написания этих слов я прямо в CPU Windows прервал программу нажав Reset. Запускаю заново. Останавливается на showmessage(p)
Смотрю в Watch List, а таам:
p: "H
← →
default (2003-04-14 19:04) [46]перед кем мне выпендриваться?!
просто код может сказать за десятки слов
мне-то это не надо...
← →
default (2003-04-14 19:06) [47]to Giemgo
какой AV?
переписывай код лучше
я всегда проверяю код в действии перед тем как скидываю его на формум
← →
icWasya (2003-04-14 19:08) [48]не забудь выключать оптимизацию
← →
icWasya (2003-04-14 19:17) [49]Вот мой код:
procedure TForm1.Button1Click(Sender: TObject);
var P:PChar;
begin
P:="Hello";
showmessage(P); //Здесь стоит брекпойнт
end;
в окне Watch
@P $68F350
P Hello
P,p $442F18
в окне CPU
по адресу $68F350 - 18 2F 44 00
по адресу $442F18 - 48 65 6C 6C 6F 00 Hello.
← →
jack128 (2003-04-14 19:18) [50]Уж нtзнаю как ты там смотрел. лично я первый раз пользуюсь окном CPU и все нашел там где оно и должно находится...
@P = 12F5DC, по этому адресу находится значение 00442А18 (значение указателя p), а по адресу 00442A18, как и дОлжно находится слово Hello. Единственно что, значение лежащее по адресу 12F5DC я смотрел в правом, а не левом нижнем окне(у не знаю имеет это какое то значение или нет)
← →
jack128 (2003-04-14 19:22) [51]
> default © (14.04.03 19:06
Это видимо мне?
Делать мне нечего вручныю печатать, Copy and Paste Вот мой девиз!! :-)
Единственное. я убрал из Uses Variants (у мя D5)
← →
default (2003-04-14 19:29) [52]jack128
не знаю у меня D6( всё работает как и должно...)
← →
Giemgo (2003-04-14 21:03) [53]Ха, ха. Поздравьте меня, я схожу с ума.
После серии экспериментов выяснил (если так можно сказать).
Создаю новый проект, кладу на форму батон. Далее можете читать Giemgo (14.04.03 18:56) начиная с третьей строчки. То есть, @p указывает вовсе не на байты, которые если интерпетировать как адрес получишь местоположение Hello.
Ха ха. Сохраняю проект. Выгружаю дельфи, тыкаю два раза на сохраненном проекте. Загружается дельфя с проектом. Запускаю. Все ок. То есть, @p указывает на байты по адресу которых лежит строка Hello. Ха ха.
Загружаю Delphi5. Тоже самое. Ха ха. То есть, создаю новый проект, ввожу код. @p опять указывает хрен знает куда. Сохраняю проект, загружаю его, компилирую, все ок. Ха ха.
Кстати, когда загружаешь сохраненный проект, то описанная выше ошибка не возникает. То есть, после прерывания выполнения приложения и его повторого запуска в Watch List"е P не отображается как "H
← →
Fantasist. (2003-04-14 21:40) [54]
> Бросаю программирование,
Бросай, в натуре. :) Что-то ты в нем по странным камням ходишь, причем много раз.
> p: "Hello" - как бы все ок
> @p: $12F5BC
>
> Перехожу по адресу $12F5BC. Для этого вызываю CPU Window
> и в нижнем левом поле жму Goto Address.
>
> По этому адресу расположен байт (и следующие за ним три
> байта):
>
> FC F6 12 00 - что вовсе не похоже на Hello
А кто только что говорил, что все понял? Вот это вот:
> @p: $12F5BC
адрес переменной p. Что мы находим, перейдя по этому адресу? Правильно, пременную p, и не понятно, что тебя тут так удивляет. Теперь бери, то что ты там увидел - это и будет значение p, которое является адресом первой буквы твоего ненаглядного "Hello".
← →
Giemgo (2003-04-14 22:06) [55]Так, волевым усилием идею нажраться я отбросил, стал разбираться...
Ура, мы победили сырость ! Наконец-то понял откуда ноги растут.
Все дело было как раз в оптимизации. Но не стоит меня упрекать, я не знал, что дельфи так себя ведет, и, по моему, это глюк.
Обьясняю подробнее.
Загружаю Дельфи. Пишу вышеупомянутые строки. Оптимизация, естесственно, по умолчанию включена. Запускаю. Далее можете читать Giemgo (14.04.03 18:56)
Почему же я не подумал об отключении оптимизации ? А потому что я ее отключал, запускал приложение и получал тот же самый результат ! Но, блин. Альдебаран я ! (хотя догадаться было сложно). Как я потом выяснил, дельфи, судя по всему, не компилирует ЗАНОВО код, если изменений в проекте только изменения галочки у оптимизации. Вот сволочи в борланде.
То есть, дельфи компилирует заново только если есть изменения в коде, то есть в редакторе кода пометка Modified. А у меня ведь изменения только в опциях проекта. И хотя с новыми опциями код получается другой, дельфи его не компилирует заново. А просто запускает существующий exe"шник. Я то нажимал F9.
В общем, после того как я отключал отпимизацию, делал Build All,а ТОЛЬКО потом уж нажимал F9 все стало работать. Ура !
Кто-нибудь знал о таком, что дельфи не компилирует при изменениях в опциях проекта ? Я лично нет - сколько ж нервных клеток загублено :)))
завтра пойду разбираться с sendto. Ждите вопросов :)
Засим откланиваюсь
P.S. "Глюки" с оптимизацией и сохранение проекта просто совпали. Так как я отключал оптимизацию, потом сохранял проект. А потом его загружал. И он, естесственно, заново компилировался и все ок :) Я уж просто стал грешить на все подряд
P.S.S А в чем заключалась оптимизация, что по адресу @p лежали левые данные ?
А, вот..
Насчет разницы между ссылкой и указателем , это в книги...Растекаться мысью по древу времени нет
Может в двух словах ?
← →
Giemgo (2003-04-14 22:15) [56]Fantasist
а нефига
А кто только что говорил, что все понял? Вот это вот:
> @p: $12F5BC
адрес переменной p. Что мы находим, перейдя по этому адресу? Правильно, пременную p, и не понятно, что тебя тут так удивляет. Теперь бери, то что ты там увидел - это и будет значение p, которое является адресом первой буквы твоего ненаглядного "Hello".
Я же писал ниже
>Если перейти по адесу 00 12 F6 FC то там тоже Hello нету.
Ну собственно говоря все уже понято. Оптимизация и дельфи слишком умная виновата (ну и да, да, кривые руки тоже).
Пусть она уж каждый раз заново xe"шник делает...
← →
А123 (2003-04-14 22:57) [57]Сколько мучений и флейма! А все из-за того, что автор не обратил внимания или не захотел перевести на русский сообщение об ошибке:
>то почему компилятор мне сообщает:
>[Error] Unit1.pas(44): Constant object cannot be passed as var >parameter
И упорно пытался найти способ передать в функцию константу вместо переменной.
← →
default (2003-04-14 23:18) [58]"Но, блин. Альдебаран я !" это ещё слабо сказано
извиняйся за свою тупизну давай прилюдно ха ха ха
← →
Giemgo (2003-04-15 00:03) [59]Хм. Ну может я и ламер, спорить не буду.
Но скажите честно - ВЫ ЗНАЛИ, что дельфи не будет компилировать код заново, если изменить галочку оптимизации в свойствах проекта и нажать Run ?! Хотя код получается другим и он ДОЛЖЕН заново его скомпилировать по логике.
default, ты об этом знал ?
to А123
>то почему компилятор мне сообщает:
>[Error] Unit1.pas(44): Constant object cannot be passed as var >parameter
И упорно пытался найти способ передать в функцию константу вместо переменной
Я то обратил на это внимание. И оффигел от твоего поста. Ты сам понял, что написал ? Если понял, то:
1) Каким образом данный Error связан с оптимизацией ?
2) Ты только что присоединился ? Если ты читал посты последовательно, то должен был заметить, что мне предлагали вместо PChar использовать string таким образов: PChar(s). А я отвечал, что это недопустимо, так как нужно передавать по ссылке переменную, и тогда PChar(s) не подходит. Как подтверждение привел данный Error.
← →
А123 (2003-04-15 01:09) [60]2 Giemgo (15.04.03 00:03)
Про оптимизацию не дочитал, уж слишком много.
Пардон, действительно не все внимательно прочел и не понял, что "данный Error" лишь ответ на ответ, а не "источник". Однако, имхо, PChar(s) в общем случае не может приводить к "данный Error".
Страницы: 1 2 вся ветка
Текущий архив: 2003.04.24;
Скачать: CL | DM;
Память: 0.58 MB
Время: 0.009 c