全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2181
推到 Plurk!
推到 Facebook!

GetMem與AllocMem造成的差異

答題得分者是:sryang
cookiecs
一般會員


發表:1
回覆:2
積分:0
註冊:2010-11-05

發送簡訊給我
#1 引用回覆 回覆 發表時間:2010-11-18 18:32:07 IP:124.219.xxx.xxx 訂閱
各位前輩好:

小弟遇到一個問題百思不得其解,想請教各位前輩。

假設ClientSocket用ClientSocket.Socket.SenText 傳送
第一個String ('1234567890');
第二個String ('1234567890ab');

ServerSocket進行以下處理:----簡短板---
var tpoint:pointer;
tBuffer:AnsiString;
ti:Integer;
=====================
ti:=Socket.ReceiveLength;
GetMem(tpoint,ti);
Socket.ReceiveBuf(tpoint^,ti);
tBuffer:=StrPas(PAnsiChar(tpoint));
Label.Caption(tBuffer);
FreeMem(tpoint);



問題:
第一個顯示的是 1234567890pt,用Debug看的是 '1234567890pt'#1
第二個顯示的是 1234567890ab,用Debug看的是 '1234567890ab'#1 (顯示正常)

但是如果紅色那邊改成
tpoint:=Allocmem(ti); 就都是正常顯示。

可以請問是什麼原因造成的嗎?

希望能有人解惑。謝謝

註:使用版本,Delphi 2010
------
一切只是懵懵懂懂
編輯記錄
cookiecs 重新編輯於 2010-11-18 03:33:01, 註解 無‧
cookiecs 重新編輯於 2010-11-18 03:43:48, 註解 無‧
sryang
尊榮會員


發表:38
回覆:741
積分:875
註冊:2002-06-27

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-11-19 07:23:37 IP:111.254.xxx.xxx 訂閱
StrPas 要遇到 #0 才會停止

而 AllocMem 是呼叫 GetMem 之後,再呼叫 FillChar 填入 #0,所以會正常
如果你要用 GetMem 的話,記得後面加一行 FillChar(pointer^, size, #0)

否則你一 StrPas 下去,就使用到不屬於你的記憶體了

如果是寫入的話,這種 BUG 就叫做「緩衝區溢位」,是很危險的動作!!
輕則資料異常,程式當掉,重則被利用來殖入惡意程式碼進而控制你的系統。
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
cookiecs
一般會員


發表:1
回覆:2
積分:0
註冊:2010-11-05

發送簡訊給我
#3 引用回覆 回覆 發表時間:2010-11-19 09:16:17 IP:124.219.xxx.xxx 訂閱
謝謝Sryang的回答,這是很寶貴的學習經驗。

===================引 用 sryang 文 章===================
StrPas 要遇到 #0 才會停止

而 AllocMem 是呼叫 GetMem 之後,再呼叫 FillChar 填入 #0,所以會正常
如果你要用 GetMem 的話,記得後面加一行 FillChar(pointer^, size, #0)

否則你一 StrPas 下去,就使用到不屬於你的記憶體了

如果是寫入的話,這種 BUG 就叫做「緩衝區溢位」,是很危險的動作!!
輕則資料異常,程式當掉,重則被利用來殖入惡意程式碼進而控制你的系統。
------
一切只是懵懵懂懂
cookiecs
一般會員


發表:1
回覆:2
積分:0
註冊:2010-11-05

發送簡訊給我
#4 引用回覆 回覆 發表時間:2010-11-19 13:29:12 IP:124.219.xxx.xxx 訂閱
自己測試了一下又出現一些問題,想再次請教

這是使用的是AllocMem,當ClientSocket.Socket.SendText('12345678');
結果又造成了顯示異常,所以測試了一下。

ty:=Length(PAnsichar(tpointer));----->{9}

請問為什麼會多出 1 個長度呢?
------
一切只是懵懵懂懂
sryang
尊榮會員


發表:38
回覆:741
積分:875
註冊:2002-06-27

發送簡訊給我
#5 引用回覆 回覆 發表時間:2010-11-19 13:38:26 IP:122.146.xxx.xxx 訂閱
Length 接收的參數是 string,所以當你傳入 PAnsiChar(pointer) 時,會強制轉型
此時仍然要遇到 #0 才會停止

所以,"接收 buffer 大小" 最好是 ReceiveLength 1
配合 AllocMem 取得 buffer 時,就可以保證 buffer 的最後一個 byte 一定是 #0
這樣就不會出現結尾多字的狀況了
------
歡迎參訪 "腦殘賤貓的備忘錄" http://maolaoda.blogspot.com/
系統時間:2017-10-23 12:23:47
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!