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

Вниз

Функция копирования PChar в string   Найти похожие ветки 

 
MetalFan ©   (2006-10-16 17:57) [0]

что необходимо:
1) копировать содержимое string в Pchar
2) выделять/перевыделять память под PChar
3) очищать PChar, если длинна string = 0;

вот написана такая функция
function SetPChar( var APChar: PChar; const ACopyString: string): PChar;
 var
   lLenStr: Integer;
 begin
   Result := nil;
   lLenStr := Length(ACopyString);
   if (APChar = nil) and ( lLenStr= 0) then Exit;
   if lLenStr = 0 then
   begin
      FreeMem( APChar{, 0});
      APChar := nil;
   end
   else
   begin
     ReallocMem( APChar, lLenStr + 1);
     //Result := StrLCopy(APChar, PChar(ACopyString), lLenStr);
     CopyMemory( APChar, @ACopyString[1], lLenStr);
     APChar[lLenStr] := #0;
   end;
   Result := APChar;
 end;

оцените ее правильность %) что-то никак не соображу, есть ли тут косяки...


 
Desdechado ©   (2006-10-16 18:03) [1]

var p:Pchar;
s:String;

s:=String(p);
p:=PChar(s);


 
MetalFan ©   (2006-10-16 18:08) [2]

а происходит ли при это копирование содержания s и з.
если p - внешнияя переменная, а s внутренняя, то после оконачния процедуры, где объявлена s, p будет указывать в... на... короче не туда)
или нет?


 
Eraser ©   (2006-10-16 18:08) [3]

> [1] Desdechado ©   (16.10.06 18:03)


> s:=String(p);

s := p;
UniqueString(s);


> p:=PChar(s);


p := PChar(s);


 
MetalFan ©   (2006-10-16 18:33) [4]

мм... и что, весь функционал в [0] оказывается ненужным?! )


 
Ketmar ©   (2006-10-16 18:40) [5]

>[4] MetalFan(c) 16-Oct-2006, 18:33
>мм... и что, весь функционал в [0] оказывается ненужным?! )
угу. "наука умеет много гитик" (ц) %-)


 
Leonid Troyanovsky ©   (2006-10-16 18:43) [6]


> MetalFan ©   (16.10.06 18:08) [2]

> если p - внешнияя переменная, а s внутренняя, то после оконачния
> процедуры, где объявлена s, p будет указывать в... на...
>  короче не туда)


Конечно, в никуда.
Самое простое - поменять ролями s & p, т.е., пусть p - внутренняя.
Ну, а освобождать строку просто: s := ""

--
Regards, LVT.


 
MetalFan ©   (2006-10-16 19:04) [7]

нет, функция должна однозначно копировать содержимое входной string  в pchar, чтобы дальнейшая судьба string"а никак не влияла на резульирующий pchar.

ладно, вопрос тот же: нет ли ошибок в функции в [0]?.
просто интересно мнение...


 
Ketmar ©   (2006-10-16 19:09) [8]

на:
function SetPChar (var aPChar: PChar; const aCopyString: string): PChar;
var
 lLenStr: Integer;
begin
 lLenStr := Length(aCopyString);
 ReallocMem(aPChar, lLenStr);
 if lLenStr > 0 then Move(aCopyString[1], aPChar^, lLenStr+1);
 result := aPChar;
end;


 
MetalFan ©   (2006-10-16 19:12) [9]


> Ketmar ©   (16.10.06 19:09) [8]

а #0 в конце разве будет? или в string"е тоже #0 в кноце "висит"?


 
Ketmar ©   (2006-10-16 19:12) [10]

>[9] MetalFan(c) 16-Oct-2006, 19:12
>а #0 в конце разве будет? или в string"е тоже #0 в кноце "
>висит"?
rtfm.


 
Ketmar ©   (2006-10-16 19:13) [11]

натурально, справедливо только для {$H+}.


 
MetalFan ©   (2006-10-16 19:30) [12]

с этим
> Ketmar ©   (16.10.06 19:09) [8]
вместо этого [0] проэкт просто "умирает" с AV сразу после вызова...


 
Ketmar ©   (2006-10-16 19:33) [13]

>[12] MetalFan(c) 16-Oct-2006, 19:30
>вместо этого [0] проэкт просто "умирает" с AV сразу после
>вызова...
ищи у себя баг.

{$APPTYPE CONSOLE}

function SetPChar (var aPChar: PChar; const aCopyString: string): PChar;
var
 lLenStr: Integer;
begin
 lLenStr := Length(aCopyString);
 ReallocMem(aPChar, lLenStr);
 if lLenStr > 0 then Move(aCopyString[1], aPChar^, lLenStr+1);
 result := aPChar;
end;

var
 s: string;
 p: PChar;
begin
 p := nil; s := "test";
 SetPChar(p, s); WriteLn(""", p, """);
 s := "t1";
 SetPChar(p, s); WriteLn(""", p, """);
 s := "";
 SetPChar(p, s); if p > nil then WriteLn("!");
end.


всё работает.


 
Loginov Dmitry ©   (2006-10-16 19:51) [14]

Ketmar ©   (16.10.06 19:33) [13]
ReallocMem(aPChar, lLenStr);


Единичку к lLenStr было бы неплохо приплюсовать, имхо


 
Palladin ©   (2006-10-16 19:51) [15]


> [13] Ketmar ©

Это как? Резервируешь Length, а Move делаешь на Length+1 ? ай ай ай... :)


> всё работает.

Ага, "по встречке тоже можно ехать" (с) :)


 
MetalFan ©   (2006-10-16 20:03) [16]

с учетом след.изменений валиться все перестало %)
var
  lLenStr: Integer;
 begin
  lLenStr := Length(aCopyString);

  if lLenStr > 0 then
  begin
   ReallocMem(aPChar, lLenStr+1);
   Move(aCopyString[1], aPChar^, lLenStr+1);
  end
  else
    ReallocMem(aPChar, 0);
  result := aPChar;


 
Ketmar ©   (2006-10-16 20:03) [17]

ай. ай. ай. каюсь. посыпаю тыкву пеплом. больше не буду спросонья код давать! таки налажал. код прошу считать недействительным. %-)


 
Ketmar ©   (2006-10-16 20:04) [18]

зыж не зря я свои проекты начинаю писать только часа через 4 после того, как проснусь. %-)


 
MetalFan ©   (2006-10-16 20:09) [19]

2 Ketmar ©  [17,18]
да ладно, ерунда)
спасибо за помощь в оптимизации кода!


 
Leonid Troyanovsky ©   (2006-10-16 20:10) [20]


> MetalFan ©   (16.10.06 19:04) [7]

> string  в pchar, чтобы дальнейшая судьба string"а никак
> не влияла на резульирующий pchar.


Обычно в этих случаях поступают так:

Допустим, что p - указатель на буфер достаточного размера,
скажем, a: array [0..MAX_BUF] of Char

Тогда нам достаточно сделать StrPCopy(a, s).
Хотя, конечно, предпочтительней StrPLCopy.

Если такого массива нет, то для начала, распределим
буфер (StrAlloc, GetMem), как минимум Length(s)+1 байт.
Ну, а далее - StrP(L)Copy.

Когда в оной строке более нет нужды делаем StrDispose/FreeMem.

Больше, собс-но, ничего не нужно.
Хотя, конечно, вышеописанное легко сделать и с помощью Move.

Главное, что нет никакой необходимости писать некую функцию,
которая объединит распределение буфера и копирование в него,
бо от этого возникает одна лишь путаница.

--
Regards, LVT.


 
MetalFan ©   (2006-10-16 20:10) [21]

а, ну да, вот что в итоге у меня получилось:
function SetPChar( var APChar: PChar; const ACopyString: string): PChar;
 var
  lLenStr: Integer;
 begin
  lLenStr := Length(aCopyString);
  if lLenStr > 0 then
    inc(lLenStr);
  ReallocMem(aPChar, lLenStr);
  if lLenStr > 0 then
   Move(aCopyString[1], aPChar^, lLenStr);
  result := aPChar;
end;


 
MetalFan ©   (2006-10-16 20:12) [22]

Leonid Troyanovsky ©   (16.10.06 20:10) [20]
вне функции имеем TList, в котором хранятся таким образом выделяемые PChar"ы...


 
Ketmar ©   (2006-10-16 20:13) [23]

>[21] MetalFan(c) 16-Oct-2006, 20:10
> if lLenStr > 0 then inc(lLenStr);
угу. вот это-то я и забыл. %-) похмеляццо надо чаще. %-)


 
Leonid Troyanovsky ©   (2006-10-16 20:20) [24]


> MetalFan ©   (16.10.06 20:12) [22]

> вне функции имеем TList, в котором хранятся таким образом
> выделяемые PChar"ы...


Для этого обычно используют TStringList.
Если, вдруг, потребуются PChar делают PChar(Strings[i])

> function SetPChar( var APChar: PChar; const ACopyString:

Не надо в функции распределять память.
Возьми за правило, и волосы у тебя сохранятся гораздо дольше.

--
Regards, LVT.


 
MetalFan ©   (2006-10-16 21:43) [25]


> Для этого обычно используют TStringList.

есть необходимость использовать TList)
но спасибо за совет ;)


 
Eraser ©   (2006-10-16 23:43) [26]

в догонку:
зачем вообще упали этот PChar в Делфи... не зря есть намного более удобный типа - string. С ним и надо работать, а PChar - только для Win-API ф-ий, и то, чаще всего, можно не явно использовать.


 
icWasya ©   (2006-10-17 09:51) [27]

>>зачем вообще упали этот PChar в Делфи
А действительно, для чего понадобилось использовать и то и другое??


 
Anatoly Podgoretsky ©   (2006-10-17 10:05) [28]


> А действительно, для чего понадобилось использовать и то
> и другое??

В Дельфи PChar использовать не требуется. String полностью совместим с PChar

> только для Win-API ф-ий, и то, чаще всего, можно не явно
> использовать.

И там не требуется, а если функция возращает PChar, то никому не запрещено сделать S := PChar



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

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

Наверх




Память: 0.54 MB
Время: 0.052 c
2-1162928915
Alral
2006-11-07 22:48
2006.11.26
RemoteAddress, RemoteHost...


15-1162897495
DiamondShark
2006-11-07 14:04
2006.11.26
Отцы, посоветуйте ламеру.


15-1163084803
Slaga
2006-11-09 18:06
2006.11.26
Передать файл с сервера на клиент и наоборот


5-1144329234
Alex Romanskiy
2006-04-06 17:13
2006.11.26
Компоненты для работы с MySQL


6-1152561807
papaP
2006-07-11 00:03
2006.11.26
Проблемы с логином на сайт(юзая Indy)