返回pchar的函数(100分)

  • 主题发起人 主题发起人 张鸿林
  • 开始时间 开始时间

张鸿林

Unregistered / Unconfirmed
GUEST, unregistred user!
调用返回pchar的函数,结果无法预料

unit pcharFunc.pas
interface
uses SysUtils ;
function test:pchar;

implementation
function test:pchar;
var acount:integer;
s:string;
begin
acount:=0;
s:=pchar('第'+inttostr(aCount+1)+'个改码方案中缺少")"')
//如果 s:='sdfdsfsdf' ,一个常量,则没有问题
result:=pchar(s);//给pchar直接赋值,应该可以省略为pchar分配空间

end;

另外一个单元:
procedure TForm1.Button1Click(Sender: TObject);
begin
edit3.Text:=SCH_ModiSizeExpValidCheck(pchar(edit1.text),pchar(edit2.text));
end;
procedure TForm1.Button1Click(Sender: TObject);
var p,p1:pchar
i:integer;
begin
p:=test;
p1:=p;
edit1.text:=(p1);
showmessage(p1);
end;
这时我们可以发现,edit1.text和showmessage(p)不一样,且结果无法预料
如果 function test 跟调用者同一个单元,结果正常
 
function test:pchar;
var acount:integer;
s:string;
begin
acount:=0;
s:=pchar('第'+inttostr(aCount+1)+'个改码方案中缺少")"')
//如果 s:='sdfdsfsdf' ,一个常量,则没有问题
result:=pchar(s);//给pchar直接赋值,应该可以省略为pchar分配空间

end;

s:string
改为全局变量

 
function test:pchar;
var acount:integer;
s:string;
begin
acount:=0;
s:=pchar('第'+inttostr(aCount+1)+'个改码方案中缺少")"')
//如果 s:='sdfdsfsdf' ,一个常量,则没有问题
result:=pchar(s[1]);//给pchar直接赋值,应该可以省略为pchar分配空间

end;
 
自己领会原因吧:
function test:pchar;
var acount:integer;
s:string;
begin
......
result:=pchar(s);
[red] Inc(PInteger(Integer(result)-8)^)
<-- 加这一行,注意: s不能为常量[/red]
end;

procedure TForm1.Button1Click(Sender: TObject);
....
showmessage(p1);
[red] string(p1) := ''
<-- 加这一行释放内存[/red]
end;
 
test的返回是指向局部变量s的,而在test返回后,test所用的堆栈已被释放,得到想不到的结果也不冤。
可以在test内部用getmem之类的函数在堆里分配空间,并且返回这个指针就可以了。
 
查了delphi的帮助:
Returning a PChar local variable
A common error when working with PChars is to store a local variable in a data structure, or return it as a value. When your routine ends, the PChar disappears because it is a pointer to memory, and not a reference counted copy of the string. For example:

function title(n: Integer): PChar;
var
s: string;
begin
s := Format('title - %d', [n]);
Result := PChar(s)
// DON'T DO THIS
end;

This example returns a pointer to string data that is freed when the title function returns.
 
我在为Interbase写函数,不得不使用pchar
Another_eYes的方法或许可用,我测试一下然后给大家汇报
 
谢谢大家,总结一下
Inc(PInteger(Integer(result)-8)^)

可用
但是,因为我是为数据库脚本写函数,所以,释放这块内存将成为问题
 
s:string
改为全局变量
或 array of char
在 finalization 清空s


 
思考了一下,
hfghfghfg 确实是一个简单可用的方法,谢了

刚才结单没有成功?
 
多人接受答案了。
 
const MaxYourCount=200;
var TmpBuf:Array[0..MaxYourCount] of Char;
function Test:PChar;
var acount:integer;
begin
acount:=0;
FillChar(TmpBuf,Sizeof(Tmpbuf),0);
StrCopy(TmpBuf,PChar(Format('第%d个改码方案中缺少',[Acount+1])));
Result:=TmpBuf;
end;
 
后退
顶部