|
|
导航: |
论坛 -> DELPHI技术
斑竹:liumazi,sephil |
|
作者: |
|
2010/11/13 16:14:40 |
标题: |
string 和 array of char 之间的转换问题 |
浏览:3619 |
|
加入我的收藏 |
楼主: |
我的程序如下: var S: string; Darr: array of char; p:pchar; begin s:= '中文'; SetLength(Darr,Length(s)); Move(s,Darr[0],Length(S)); try GetMem(p,Length(Darr)); Move(Darr[0],p,Length(Darr)); showMessage(p); finally FreeMem(p); end; end; showMessage的结果是“中文”。但是最后报错:“Invalid pointer operation”,用的D6。不知道什么原因。
----------------------------------------------
- |
作者: |
|
2010/11/13 16:48:24 |
1楼: |
不懂指针,但是看try结构似乎不对
GetMem(p,Length(Darr)); try 。。。。 finally FreeMem(p); end;
----------------------------------------------
我打的是酱油,而不是别的什么油。 我灌的是口水,而不是别的什么水。 我聊的折腾不是那个不折腾的折腾。 我说的阿娇不是那个邓玉娇的阿娇。 3个代表,6个为什么,9个肠胃炎。 D性强的领导干部都不喜欢热比娅。 我特别要讲的是,屁民网黄色论坛是我经常上网必选的 网站之一
|
作者: |
|
2010/11/13 17:46:50 |
2楼: |
在dlphi2010下测试,出现“Invalid pointer operation”的原因主要是FreeMem(P),原因应该是Pchar类型是自管理的,不用FreeMem,事实上也不必用GetMem。而且上述用Length的话不能显示正确内容,改为SizeOf就OK。测试代码如下: procedure TForm1.btn1Click(Sender: TObject); var Str:string; P:PChar; Arr:array of Char; begin str:='中文'; SetLength(Arr,sizeof(str)); Move(str,Arr[0],sizeof(Str));
try // GetMem(P,sizeof(Str)); Move(Arr[0],P,sizeof(Arr)); ShowMessage(P); finally // FreeMem(P); end;
----------------------------------------------
-
|
作者: |
learu (learu) |
★☆☆☆☆ |
-
|
盒子活跃会员 |
|
2010/11/13 18:20:15 |
3楼: |
真对现在的程序员悲哀啊...(不是对楼主) 如果自己都没明确搞明白 请不在乱回答别人好不好!!
TO 2楼: 是谁告诉你PChar类型是自管理的了? 不知道写的什么乱七八糟的... 自己错就算了 不要误导别人 OK
----------------------------------------------
-
|
作者: |
learu (learu) |
★☆☆☆☆ |
-
|
盒子活跃会员 |
|
2010/11/13 18:30:30 |
4楼: |
var S: Ansistring; Darr: array of Ansichar; p:pAnsichar; begin s:= '中文'; SetLength(Darr,Length(s)); Move(s[1], Darr[0], Length(S)); p := AllocMem(Length(Darr)+1); try Move(Darr[0], p^, Length(Darr)); showMessage(p); finally FreeMem(p); end; end;
虽然这段代码 很多都是重复多余的(是指好像没什么实际意义) 顺便解释一下跟楼主写的不同点的原因: 为什么用了AnsiString 因为D6的String = D2009,2010,XE 下的AnsiString 同理 我把 PChar都换成了 PAnsiChar, Char换成了 AnsiChar 为是只是开发环境对代码兼容 至于为什么我用 Allocmem 不是用GetMem 因为AllocMem比GetMem 多了申请完内存后会将内存全部置为0 因为指针字符器是以\0结束的 (这些好像在计算机原理或者别的基础书里都有讲 如果不懂 请看书) 所以申请空间时 你需要申请比字符串多一个字节 并且是0(如果是Unicode下就是2个字节)
---------- var S: Ansistring; Darr: array of Ansichar; p:pAnsichar; begin s:= '中文'; SetLength(Darr,Length(s)); Move(s[1], Darr[0], Length(S)+1); p := @Darr[0]; showMessage(p); end;
其实这样子就可以了 不需要又申请什么内存
----------------------------------------------
-
|
作者: |
learu (learu) |
★☆☆☆☆ |
-
|
盒子活跃会员 |
|
2010/11/13 18:35:01 |
5楼: |
至于为什么会报 Invalid pointer operation错
原因是因为 字符串指针 必须是以\0为结束
因为你申请的内存只放的下"中文"4个字节 会发生2种情况 运气好: "中文" 后面跟的是\0 且这个内存地址是有效的 那就不会报错 运气不好: 也就是你这样读字符串的时候越界了 非法指针操作
都是很基础的东西 去翻翻基础书吧
----------------------------------------------
-
|
作者: |
melice (melice) |
★☆☆☆☆ |
-
|
盒子活跃会员 |
|
2010/11/14 23:24:58 |
6楼: |
做了简单的修改,move换成copymemory,getmem换成getmemory。测试正常。 var S: string; Darr: array of char; p:pchar; l:integer; begin s:= '中文'; L := Length(s); SetLength(Darr,L); CopyMemory(@Darr[0], @s[1], L); try p := GetMemory(L+1); CopyMemory(p, @Darr[0], L); showMessage(p); finally FreeMem(p); end;
----------------------------------------------
-
|
作者: |
melice (melice) |
★☆☆☆☆ |
-
|
盒子活跃会员 |
|
2010/11/14 23:27:17 |
7楼: |
var S: string; Darr: array of char; p:pchar; begin s:= '中文'; SetLength(Darr,Length(s)); Move(s,Darr[0],Length(S)); //自己调试跟踪下这句的效果是什么。 try GetMem(p,Length(Darr)); Move(Darr[0],p,Length(Darr)); showMessage(p); finally FreeMem(p); end;
----------------------------------------------
-
|
作者: |
|
2010/11/15 8:57:59 |
8楼: |
讨论一下语法也好 var S: string;//最好是s: AnsiString Darr: array of char; p:pchar; begin s:= '中文'; Setlength(Darr, Length(s)+1);//保留最后一位给#0; //SetLength(Darr,Length(s)); Move(Pointer(s)^, Pointer(Darr)^, Length(s));//注意变量参数的传递,或引用类型参数 //或 Move(s[1], Darr[0], Length(s)); //Move(s,Darr[0],Length(S)); try GetMem(p,Length(Darr)); Move(Pointer(Darr)^, p^, Length(Darr));//注意变量参数的传递,或引用类型参数 //或Move(Darr[0], P^, Length(Darr)); //Move(Darr[0],p,Length(Darr)); showMessage(p); finally FreeMem(p); end; end;
----------------------------------------------
-
|
作者: |
|
2010/11/15 9:35:58 |
9楼: |
yzhtwo (深秋)
可以详细说说,
Move(Pointer(Darr)^, p^, Length(Darr));//注意变量参数的传递,或引用类型参数 //或Move(Darr[0], P^, Length(Darr)); //Move(Darr[0],p,Length(Darr)
吗
----------------------------------------------
---------- 短信群发 http://www.188sms.cn 家校通 http://www.studjxt.cn 网站建设 http://www.51zwz.net ----------
|
作者: |
|
2010/11/15 14:45:05 |
10楼: |
继续讨论一下 var s: Ansistring; FArr: array[1..10] of char; FDArr: array of char; P: PChar; c: Char; //对于变量名s,FArr,FDArr,P都是相对应的内存首地址(s,FDArr,P需初始化) begin try GetMem(P, 10*SizeOf(Char)); //----------
s :='0123456789'; //下面也是取得s[1]; c := PChar(s)^; //取字符串地址指向的第一个字符,也就是s[1]; ShowMessage(c);
// procedure Move( const Source; var Dest; count : Integer ); //Source, Dest参数实际上传入的是变量的地址,也就是说取变量的地址传入; //所以我们不能直接传入变量s(地址), 只能传入s[1]或PChar(s)^,让过程取s[1]取地址(字符串首地址) Move(PChar(s)^, P^, Length(s)); c := P^; ShowMessage(c); //----------
FArr := 'abcdefghij'; //下面也是取得FArr[1]; c := PChar(@FArr)^; //取数组地址指向的第一个字符,也就是FArr[1]; ShowMessage(c);
Move(FArr, P^, Length(s)); c := P^; ShowMessage(c); //----------
SetLength(FDArr, 10); //设置动态数驵长度,FDArr指向动态数组的首地址
// FDArr := 'ABCDEFGHIJ';//跟静态数组不一样,这样不可以 FDArr[0] := 'A'; FDArr[1] := 'B'; FDArr[2] := 'C'; FDArr[3] := 'D'; FDArr[4] := 'E'; FDArr[5] := 'F'; FDArr[6] := 'G'; FDArr[7] := 'H'; FDArr[8] := 'I'; FDArr[9] := 'J'; //下面也是取得fDArr[0]; c := PChar(FDArr)^; //跟静态数组有区别,不要取@操作 ShowMessage(c);
Move(PChar(FDArr)^, P^, Length(FDArr)); // 取动态数组地址指向的第一个字符传入 c := P^; ShowMessage(c); //----------
finally FreeMem(P); end; end;
----------------------------------------------
-
|
作者: |
melice (melice) |
★☆☆☆☆ |
-
|
盒子活跃会员 |
|
2010/11/15 21:20:59 |
11楼: |
又仔细看了下,lz的代码暴露了很多问题,move的含义没弄清楚,指针概念不清晰等等。showmessage可以显示完全是一种巧合。如果字符串再长一点,搞不好连整个堆栈都破坏掉了。
2次move传递的实际上是地址,而不是字符串的内容。这个才是为什么异常的核心所在啦。 至于pchar后面要多个#0,这个也是要小心的问题。
总之,对于指针的操作,要小心小心再小心。再怎么小心也是不过分的。
----------------------------------------------
-
|
作者: |
|
2010/11/17 2:35:32 |
12楼: |
string 和 array of char 之间好象很容易转换哦, 很多年前就做过了, 现在有点忘了, array of char 和 pchar可以直接转换, pchar(array of char)就行, string就复杂了点, 具体有点忘了, 但是可以转换的.
----------------------------------------------
-
|
作者: |
|
2010/11/17 2:43:04 |
13楼: |
string可以和pchar相互直接转换啊!
var a: string; b: pchar; ..... a:=string(b); b:=pchar(a);
在delphi7上完全可以互换;
----------------------------------------------
-
|
作者: |
|
2011/2/17 22:14:30 |
14楼: |
StrPCopy
----------------------------------------------
-delphi新资讯站 http://www.delphigear.cn
|
|