Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.12.13;
Скачать: CL | DM;

Вниз

xor первым 4 байтам string одной строкой   Найти похожие ветки 

 
Nucer   (2009-10-23 19:41) [0]

Можно ли исправить? Или сделать xor одной строкой в любом случае не получится?
var
s: string;
begin
s := #1#2#3#4;
ShowMessage(IntToHex(PInteger(s)^, 8)); // работает (04030201)
PInteger(s)^ := PInteger(s)^ xor $FFFFFFFF; // access violation
end;


 
palva ©   (2009-10-23 19:53) [1]

А посмотрите адрес, по которому происходит access violation
Если он нечетный, то это из-за выравнивания.
А IntToHex, наверно, обрабатывает число побайтно, поэтому ошибок не происходит.


 
palva ©   (2009-10-23 19:57) [2]

Как бы то ни было, так делать нельзя. 4 последовательных байта не всегда могут рассматриваться как целое число. Адрес первого байта должен делиться на 2 (может быть, даже на 4, поправьте, если ошибаюсь).


 
sniknik ©   (2009-10-23 20:21) [3]

var
 s: string;
begin
 s:= #1#2#3#4;
 ShowMessage(IntToHex(PInteger(@s[1])^, 8)); // работает (04030201)
 PInteger(@s[1])^:= PInteger(@s[1])^ xor $FFFFFFFF;
end;


 
begin...end ©   (2009-10-24 10:54) [4]

> Nucer   (23.10.09 19:41)

Не уверен (сейчас Delphi под рукой нет), но думаю, что Ваш пример не работает потому, что тело строки в данном случае является константой, и присвоение s := #1#2#3#4 сводится к записи в переменную s адреса этого тела. Тело такой строки-константы (сформированное, конечно, ещё на этапе компиляции) во время работы программы находится в области памяти с правами только на чтение, поэтому у Вас и не получается внести туда изменения. Дело изменится, если строка не будет константой (вероятно, в Вашей реальной программе она таковой и не является, иначе "отxorенную" строку Вы бы тоже задали как константу):

begin
 SetLength(s, 4);
 s[1] := #1;
 s[2] := #2;
 s[3] := #3;
 s[4] := #4;
 ShowMessageFmt("%x", [PInteger(s)^]);
 PInteger(s)^ := PInteger(s)^ xor $FFFFFFFF; // должно работать
 ShowMessageFmt("%x", [PInteger(s)^])
end.


Код из [3] работает, вероятно, потому, что в ходе присвоения PInteger(@s[1])^ := ... автоматически создаётся копия строки.


 
Nucer   (2009-10-24 12:19) [5]

Большое спасибо за подробные ответы.

var
sc, sd: string;
t: string;
begin
sc := #1#2#3#4;

SetLength(sd, 4);
sd[1] := #1;
sd[2] := #2;
sd[3] := #3;
sd[4] := #4;

t := t + Format("%x: %x", [Integer(sc), PInteger(sc)^]) + #13#10;
PInteger(@sc[1])^:= PInteger(@sc[1])^ xor $FFFFFFFF;
t := t + Format("%x: %x", [Integer(sc), PInteger(sc)^]) + #13#10;

t := t + Format("%x: %x", [Integer(sd), PInteger(sd)^]) + #13#10;
PInteger(@sd[1])^:= PInteger(@sd[1])^ xor $FFFFFFFF;
t := t + Format("%x: %x", [Integer(sd), PInteger(sd)^]) + #13#10;

ShowMessage(t);
end;


В результате выводится сообщение:
45228C: 4030201
95359C: FBFCFDFE
95354C: 4030201
95354C: FBFCFDFE


В случае с sd, как оказалось, PInteger(@sd[1]) равнозначно PInteger(sd).


 
sniknik ©   (2009-10-24 12:39) [6]

> PInteger(@sd[1]) равнозначно PInteger(sd).
э не, просто преобразование адреса к нужному типу, и взятие элемента из этого адреса и получение его адреса, разные вещи. код генерится разный.
вот результат (получаемый адрес) в данном случае одинаковый.

есть еще вариант. (сразу не смог вспомнить функцию, потом вспомнил как можно посмотреть :о))
var
s: string;
begin
s := #1#2#3#4;
UniqueString(s);
ShowMessage(IntToHex(PInteger(s)^, 8)); // работает (04030201)
PInteger(s)^ := PInteger(s)^ xor $FFFFFFFF; // access violation
end;


 
sniknik ©   (2009-10-24 12:40) [7]

а, ну да
> // access violation
здесь лишнее (издержки копи пасте)



Страницы: 1 вся ветка

Текущий архив: 2009.12.13;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.014 c
2-1256198587
Andrewtitoff
2009-10-22 12:03
2009.12.13
ADO не удается найти строку для обновления


1-1228487894
madmech
2008-12-05 17:38
2009.12.13
Помогите ускорить алгоритм


2-1256816360
Morgan128
2009-10-29 14:39
2009.12.13
Как отследить последнее действие клавы/мыши


15-1255523606
s_t_d
2009-10-14 16:33
2009.12.13
Книга, где есть основы работы с IDE MS Visual Studio 2008


2-1256309090
xyz
2009-10-23 18:44
2009.12.13
скопировать из TStream в файл