首頁>Club>
10
回覆列表
  • 1 # 使用者9542982168137

    我來回答題主的疑惑吧,其實是棧上資料互相覆蓋導致的。首先VB6裡Integer型別的長度是2位元組,但你CopyMemory複製的是4位元組,所以,後一條CopyMemory會寫越界。那麼再看越界行為,我個人分析,棧的記憶體分佈是這樣的:

    在程式碼一里,你的第二句CopyMemory會複製4位元組到NumPoints的地址上,但這個變數只有2個位元組,於是就把後面的Num給覆蓋了。我猜測pByte 148~152的內容應該也是00結尾的,所以最終輸出的Num值就是0反過來的程式碼二就沒有問題,但是反過來的話你的第二句CopyMemory會覆蓋到別的東西,具體是什麼就要看你程式碼怎麼寫的了。而程式碼二里第一句實際上也覆蓋了一次Num的值,不信你可以先給Num一個初始值,再在程式碼二CopyMemory(NumPoints1, pByte(148), 4)之後列印一下Num值,肯定是0如果你學一下C語言這種問題就很容易發現了。對於VB來說,CopyMemory比較危險,最可靠的做法是用len來確定要複製的記憶體大小,比如這樣就可靠多了。-------------------------------------昨天填了這個坑以後覺得好像不太對-------------------------------------於是反彙編了一下VB生成EXE檔案:不對啊,雖然integer是2位元組,但VB編譯的時候是4位元組對齊的。再看執行結果:結果居然不一樣!然後我就挨個編譯選項試了一下,發現除了生成P程式碼以外,其餘的生成的原生代碼執行結果都是1,反彙編也證明雖然integer的大小是2位元組,但生成彙編都是以4位元組對齊的。我猜題主肯定沒試過生成EXE,因為EXE的結果跟VB裡是不一樣的。那麼為什麼P程式碼以及VB裡執行時結果是不同的,只能透過反彙編P程式碼試試了。P程式碼是一種解釋型的語言,大部分實際程式碼都跑在VB的DLL裡,但透過反彙編還是可以定位到CopyMemory的位置。透過適當修改程式碼,這樣就可以更清楚的定位,可以發現在P程式碼模式裡,兩個integer確實是挨著的,沒有按4位元組對齊:總結:1. 題主這種情況肯定是不正確的,但如果生成EXE也可能會有正確的值;2. VB裡和P程式碼模式下VB採用解釋執行的方法,與直接生成原生代碼結果不同;3. 不同模型下棧上資料的對齊方式不同。-完-

  • 中秋節和大豐收的關聯?
  • 番茄醬和番茄沙司有什麼區別?