2017-08-09 31 views
0

時相剋在Linux ++編譯此代碼工作正常,但是當我嘗試在2015年VS(包括調試和釋放)來執行他們,我收到運行時錯誤。它出什麼問題了?運行時錯誤訪問時,在VS2015類成員,但不是在Linux上

#include "stdafx.h" 
#include <string.h> 
#include <iostream> 
using namespace std; 

struct Stru1 
{ 
    int mem; 
}; 

struct Stru2 : public Stru1 
{ 
    char   szMem1[256]; 
    int    dwMem2; 
    int    dwMem3; 
}; 

static void clFun(Stru1* s) { 

    Stru2* s2 = (Stru2*)s; 
    cout << s2->szMem1 << endl;//blahblah 
    cout << s2->dwMem2 << endl;//runtime error 

} 

class Temp { 
public: 

    void callDispatch() { 

     simRecv->mem = 2; 

     Stru2* sro = (Stru2*)simRecv; 
     strcpy(sro->szMem1, "blahblah"); 
     sro->dwMem2 = 11; 
     sro->dwMem3 = 77; 

     //cout << sro->szMem1 << endl;//blahblah 
     //cout << sro->dwMem2 << endl;//runtime error when uncommented 


     clFun(simRecv); 
    } 

    ~Temp() { delete simRecv; } 

    Stru1* simRecv = new Stru1; 

}; 



int main() 
{ 

    Temp tmp; 
    tmp.callDispatch(); 


    return 0; 
} 

錯誤: 異常在ConsoleApplication1.exe中在0x0000000077A0F23C(ntdll.dll中)拋出:0000005:訪問衝突讀取位置0x00000FB00188C508。

+1

所以你分配內存'Stru1',將其轉換爲'Stru2 *'它有不同的成員和所期望的一切工作。? –

+1

您已經分配了sinRecv = Stru1(帶有「new Stru1」),然後將指針投射到Stru2。 「新」分配的sizeof(Stru1),所以試圖去指向Stru2的指針正在分配結束。 – Robinson

+0

'Stru2 * sro =(Stru2 *)simRecv;' - 從這行代碼中刪除轉換。現在**仔細閱讀** [您從編譯器得到的錯誤](http://ideone.com/ISu20W)。同樣的事情[這裏](http://rextester.com/FYCVU59942)。錯誤說的是什麼?你是否聽過你的編譯器?不,你繼續申請一個演員陣容,「關閉編譯器」。 – PaulMcKenzie

回答

2
Stru2* sro = (Stru2*)simRecv; 

simRecvStru1,讓您的不安全投給Stru2是在這一行無效。

在這一行,你創建這個Stru1

Stru1* simRecv = new Stru1; 

這裏Stru1被分配到創建Stru1所需的內存,這比Stru2小。

這樣做:

Stru2* sro = (Stru2*)simRecv; 

你只是說:我有這樣的「東西」,並把它作爲一個Stru2。但是在任何地方都沒有創建new Stru2,所以對象不在那裏。

它基本上是相同的話說

I have a large wall, but I'll treat it as a house and expect a door in it.

的原因,它在不同的平臺威力的工作可以是由於平臺的不同內存分配。

至於類比:你可能可能已經到達牆的盡頭,因此不會傷到你的頭,但你不是在房子裏面,你不會離開你的錢包在那裏。

例如,該行最終將指向某個地方:

的問題是:這是有效的程序空間內?如果是的話,不會發生錯誤,但這並不意味着它是好的。您可能正在改變其他地方的變量,導致不可預知的結果。

一個例子:

PLATFORM1:

| Stru1   | some variable | some other variable   | 
| mem    | 0    | 11       | 
|     |     | ((Stru2*) simRecv)->dwMem2 | 
//no errors, but strange side effects 

PLATFORM2:

| Stru1   | some variable | some other program space | 
| mem    | 0    | ERROR: ACCES VIOLATION  | 
|     |     | ((Stru2*) simRecv)->dwMem2 | 
//0xC0000005 

如果分配Stru2(按實際創建它)擺在首位,一切都會好:

Stru1* simRecv = (Stru1*) new Stru2; 

話雖如此;這些投被認爲是不安全的(對於現在顯而易見的原因)。 另一種方法是使用例如一個static_cast。它會確保您在嘗試執行「非法」操作時會遇到構建錯誤。

http://www.cplusplus.com/doc/tutorial/typecasting/

約CPLUSPLUS附加說明,請參閱:What's wrong with cplusplus.com?

相關問題