Форум: "Основная";
Текущий архив: 2003.11.24;
Скачать: [xml.tar.bz2];
Вниз
Поменять указатель на первый символ строки. Найти похожие ветки
← →
Yuri Btr (2003-11-11 17:10) [0]Ув. мастера, у меня есть указатель (Data: PByte) на первый байт какой-то области памяти (Size - размер области) в моей программе, скажите, как можно обратиться к ней (к области) как к строке. Можно ли в процедуре явно указать, что первый символ строки располагается по адресу Data^ , а её размер равен размеру интересующей меня области. Вот таким образом - не получается. Возможно ли это в принципе?
@SourceString[1]:=Data^;
SetLength(SourceString,Size);
SourceString это локальная переменная некой процедуры.
Заранее спасибо.
← →
Reindeer Moss Eater (2003-11-11 17:15) [1]PChar(Data)
Если в конце есть #0
← →
Anatoly Podgoretsky (2003-11-11 17:15) [2]PChar
← →
mOOx_ (2003-11-11 17:17) [3]А вот так
PChar(Data);
← →
mOOx_ (2003-11-11 17:19) [4]Инет тормозит :)
← →
Yuri Btr (2003-11-11 17:20) [5]Сорри, конечно же так не проходит.
SetLength(SourceString,Size);
@SourceString[1]:=Data;
--------------------
PChar(Data) не подходит - в данной области встречается #0
посему String(PChar(Data)), сработает до первого #0
а вся остальная область будет недоступна ?
← →
Reindeer Moss Eater (2003-11-11 17:20) [6]Если нет нуля в конце блока памяти:
var pStr:PChar;
begin
pStr:=StrAlloc(Size);
StrLCopy(pStr,PChar(Data),Size);
end;
← →
Reindeer Moss Eater (2003-11-11 17:22) [7]Если внутри блока есть нули, то Move.
Но с полученной "строкой" все равно нельзя будет работать как со строкой
← →
Yuri Btr (2003-11-11 17:25) [8]to Reindeer Moss Eater ©
понимаете, эта область представляет собой отображаемый в память файл. А он может быть очень большим...
Раньше я делал копию области в строку
var
p1,p2:pointer;
.....
SetLength(SourceString,Size);
p1:=Data;
p2:=@SourceString[1];
CopyMemory(p2,p1,Length(SourceString));
но скорость не устраивала, к тому же зачем копировать данные в новую переменную SourceString, если они уже есть в программе и начинаются с Data, вот я и подумал что можно ли расположить строку в памяти с указателя Data.
← →
Reindeer Moss Eater (2003-11-11 17:27) [9]тебе же русским языком сказали, что можно.
Но работать с этим куском памяти как со строкой - забудь
← →
Yuri Btr (2003-11-11 17:29) [10]to Reindeer Moss Eater ©
Пока вам писал, вы мне уже ответили :)
Reindeer Moss Eater © (11.11.03 17:22) [7]
Мне и не надо ничего удалять, или изменять - только доступ к символам. Спасибо.
← →
Digitman (2003-11-11 17:30) [11]лучше не делай этого
по двум соображениям
1. формат внутренней упр.структуры, которую определяет переменная SourceString (фактически это - указатель на структуру), может меняться от версии к версии
2. указав тем или иным образом некорректный (с т.з. прав доступа к странице) адрес, по которому находятся нужные строковые данные, ты рискуешь как минимум получить EInvalidPointer или AV, когда структура будет автоматически уничтожаться и будет произведена попытка освобождения блока памяти, на который "смотрит" подмененный тобой указатель
← →
Yuri Btr (2003-11-11 17:37) [12]to Digitman ©
т.е. для быстрого доступа к области памяти лучше зная начальный указатель (Data) и нужное смещение символа (напр. Offset)- вручную обращаться по сумме Data+Offset, пока не достигнем Data+Size ?
и лучше ничего нет ...
← →
Digitman (2003-11-11 17:38) [13]
> Yuri Btr
Как я понял, фактически ты ведешь речь НЕ о подмене указателя, а о явном преобразовании типа перед операцией присвоения полученного значения некоей строк.переменной. А это две разные разницы.
SetLength(SourceString,Size); // сначала резервируем память в Size байт
strlcopy(PChar(SourceString), pchar(Data), Size); // и лишь теперь копируем туда Size байт из источника !!
← →
Digitman (2003-11-11 17:40) [14]
> для быстрого доступа к области памяти
для этого вообще нужно стараться избегать везде где это возможно использования типа String
← →
Yuri Btr (2003-11-11 17:45) [15]to Digitman ©
Ваш пример копирует лишь до первого символа #0.
Вернее он копирует всю Size, но после обращения к String, всё что после первого попавшегося символа #0 становится тоже #0.
Это "ограничение" Pchar. Но что делать, если нужно работать и с такими символами, аот я и подумал о String.
← →
han_malign (2003-11-11 17:50) [16]> по сумме Data+Offset, пока не достигнем Data+Size
- по моему, должно проходить - PChar(Data)[Offset] (естественно с проверкой Offset<Size)
ch:=PChar(Data)+Offset ^; - проходит точно...
> SetLength(SourceString,Size); // сначала резервируем память в Size байт
> strlcopy(PChar(SourceString), pchar(Data), Size); // и лишь теперь копируем туда Size байт из источника !!
- в System давно уже есть SetString(DestString,PChar(Data),Size);
← →
Digitman (2003-11-11 17:50) [17]
> Ваш пример копирует лишь до первого символа #0.
тогда вместо strlcopy() используй Move()
последняя копирует безо всяких проверок
← →
Yuri Btr (2003-11-11 17:55) [18]to Digitman ©
А это я уже делал посмотрите пожалуйста..
Yuri Btr © (11.11.03 17:25) [8]
to han_malign ©
SetString - ?
посмотрю...
Но проблему это не решает.. посмотрите выше пост № 8
← →
Digitman (2003-11-11 18:03) [19]
> Yuri Btr
я не понимаю, какие такие "проблемы")
собственно копирование что в [8] что в [17] выполняется корректно и без прооблем, разве что в [8] зачем-то доп.переменные введены
другой вопрос, что т.н. "проблемы" встают после копирования в полный рост, ибо в стр.данных, которые ты скопировал, содержат нуль-терминаторы, и они рано или поздно дадут о себе знать при обращении к разного рода ф-циям, оперирующими переменными типа String.
ты лучше вот что поясни - ну скопировал ты, предположим, теперь строковая переменная содержит вот такие "хитрые" стр.данные, что дальше плпнируешь с этой переменной делать ? как использовать ?
← →
han_malign (2003-11-11 18:11) [20]Дык, ты объясни - зачем тебе именно строка.
Если для поэлементного обращения - PChar(Data)[Offset],
если s:=Copy(Data,i,cnt) - то SetString(s,PChar(Data)+i,cnt),
а вот Delete, Pos и конкатенация - ручками...
> они рано или поздно дадут о себе знать при обращении к разного рода ф-циям, оперирующими переменными типа String
- неправда ваша, как раз для String, символ #0, такой же симовл как и все остальные, проблемы начинаются только при преобразовании к ASCIIZ-строке и обратно.
← →
Digitman (2003-11-11 18:33) [21]
> han_malign
вот это, по-твоему, неправда ?))
const str: PChar = "ABC" #0"DEF"; // 7 байт (+1 на финальный терминатор)
procedure TForm1.Button2Click(Sender: TObject);
var
data: PByte;
ds: String;
begin
data := Pointer(str);
setlength(ds, 7);
copymemory(PChar(ds), data, 7);
showmessage(inttostr(length(ds))); // что видим ? 7-ку видим, иного и не ожидалось
showmessage(ds); // а здесь что видим ? правильно, "ABC" видим !
end;
и где здесь эски-преобразование ? даже неявного нет в коде, вставленном компилятором !
в конечном итоге будет вызвана ExtTextOut(), которая оперирует указателем на нуль-терминированную строку
← →
Yuri Btr (2003-11-11 18:41) [22]to han_malign ©
to Digitman ©
только для поиска вхождений искомой строки в отображаемый файл, и получения смещений.
т.е. строка может быть и read-only.
Просто я не "вижу" смысла в копировании участка памяти, если он уже имеется в программе.Вот поэтому и предложил подменить указатели. Конечно я мог и ошибиться, предположив такой "хитрый" ход
← →
Digitman (2003-11-12 08:10) [23]
> только для поиска вхождений искомой строки в отображаемый
> файл, и получения смещений.
все равно непонятно, заче для этого string-тип понадобился
← →
Reindeer Moss Eater (2003-11-12 11:49) [24]Видимо кроме Pos ничего не знает
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.11.24;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.021 c