p=pchar(str)后p指向的字符串后面有#0吗? ( 积分: 50 )

  • 主题发起人 主题发起人 yth
  • 开始时间 开始时间
Y

yth

Unregistered / Unconfirmed
GUEST, unregistred user!
我感觉好像有#0,是不是string本身已经放了#0?
也就是说,string除了前面有长度和引用计数两个intger外,后面还有#0。
否则如果字符串空间后面已经被别的变量占用,怎么放#0?
难道它需要另开一块空间存放复制品?
请教各位方家。
 
我感觉好像有#0,是不是string本身已经放了#0?
也就是说,string除了前面有长度和引用计数两个intger外,后面还有#0。
否则如果字符串空间后面已经被别的变量占用,怎么放#0?
难道它需要另开一块空间存放复制品?
请教各位方家。
 
p=pchar(str)这个强制类型转换就是在末尾加#0。
 
如果字符串空间后面已经被别的变量占用,怎么放#0
 
重新申请string的空间,就像用setlength给string重新定义长度。
 
谢谢,请问有办法证明吗?
又delphi为什么不在string后放#0呢?浪费一个字节就不用重新申请空间了。
字符串后面被占用应该很普遍吧。
 
>&gt
我感觉好像有#0,是不是string本身已经放了#0
是的,对长字符串类型已由编译器加上#0,PChar(str)并不需要重新分配内存
 
进行pchar转换时字符后必须已经存在#0
而delphi中的string类型本身已经存在#0
 
同意tyzhang的意见。
 
>>对长字符串类型已由编译器加上#0
我感觉也是这样,但我翻遍delphibbs关于string的内存存放说明,没人说有#0
有人可以证明or反证?如何证明?
 
语法问题,应先查 Object Pascal Reference,在 BBS 找多麻烦。

Delphi Language Reference
Long string types

Topic Groups See Also

A long string variable occupies four bytes of memory which contain a pointer to a dynamically allocated string. When a long string variable is empty (contains a zero-length string), the string pointer is nil and no dynamic memory is associated with the string variable. For a nonempty string value, the string pointer points to a dynamically allocated block of memory that contains the string value in addition to a 32-bit length indicator and a 32-bit reference count. The table below shows the layout of a long-string memory block.

Long string dynamic memory layout
Offset Contents
-8 32-bit reference-count
-4 length in bytes
0..Length - 1 character string
Length NULL character


The NULL character at the end of a long string memory block is automatically maintained by the compiler and the built-in string handling routines. This makes it possible to typecast a long string directly to a null-terminated string.
For string constants and literals, the compiler generates a memory block with the same layout as a dynamically allocated string, but with a reference count of -1. When a long string variable is assigned a string constant, the string pointer is assigned the address of the memory block generated for the string constant. The built-in string handling routines know not to attempt to modify blocks that have a reference count of -1.

 
//但我翻遍delphibbs关于string的内存存放说明,没人说有#0
//有人可以证明or反证?如何证明?

代码为证(摘自 System.pas):

function _NewAnsiString(length: Longint): Pointer;
{$IFDEF PUREPASCAL}
var
P: PStrRec;
begin
Result := nil;
if length <= 0 then Exit;
// Alloc an extra null for strings with even length. This has no actual cost
// since the allocator will round up the request to an even size anyway.
// All widestring allocations have even length, and need a double null terminator.
GetMem(P, length + sizeof(StrRec) + 1 + ((length + 1) and 1));
Result := Pointer(Integer(P) + sizeof(StrRec));
P.length := length;
P.refcnt := 1;
PWideChar(Result)[length div 2] := #0
// length guaranteed >= 2
end;

注意中间那三行注释和最后一行代码。


如果看不懂帮助,就要学会看源码。

 
例子1.
var
str1: String
p: pchar;
begin
str1 := 'This';
p := pchar(str1);
showmessage(inttostr(ord(p[4])));
end;

例子2.
var
str1, str2: String
p: pchar;
begin
str1 := 'This';
str2 := 'This';
showmessage(inttostr(pchar(str2)-pchar(str1)));
end;

例子3.
var
str1, str2: String
p: pchar;
begin
str1 := 'This';
str2 := 'This.';
showmessage(inttostr(pchar(str2)-pchar(str1)));
end;

例子4.
var
str1: String;
str2: String;
p: PChar;
begin
str1 := 'This is a test...';
str1[5] := Chr(0);
p := PChar(str1);
ShowMessage(IntToStr(Length(p)));
str2 := Copy(str1, 1, 10);
ShowMessage(IntToStr(Length(str2)));
end;
 
你可以反向推知。如果没有的话,那么在PChar(str)形式把字符串传递到Win32API的时候,必定会导致错误。因此,必定有#0.然后为了验证,你可以动态声称一些字符串,然后在调试的时候,察看内存。
 
[blue]这个不用证明,在delphi的帮助文件里面就有详细说明。[/blue]
 

Similar threads

S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
913
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
619
import
I
后退
顶部