簡體   English   中英

在VS2015中但不在Linux上訪問類成員時出現運行時錯誤

[英]Runtime error when accessing class member in VS2015 but not on Linux

在Linux上使用g ++進行編譯時,此代碼可以正常運行,但是當我嘗試在VS 2015中執行它們(調試和發行版)時,我收到運行時錯誤。 它出什么問題了?

#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)引發異常:0xC0000005:訪問沖突讀取位置0x00000FB00188C508。

Stru2* sro = (Stru2*)simRecv;

simRecvStru1 ,因此在此行中對Stru2的不安全Stru2是無效的。

在這一行中,您將創建此Stru1

 Stru1* simRecv = new Stru1;

在這里為Stru1分配了創建Stru1所需的內存,該內存小於Stru2

通過做:

Stru2* sro = (Stru2*)simRecv;

您只是在說:我擁有這個“東西”,並將其視為Stru2 但是還沒有在任何地方創建new Stru2因此該對象不存在。

基本上和說的一樣

我有一堵大牆,但我會把它當作一所房子,並期望在其中有一扇門。

可能在不同平台上工作的原因可能是由於平台的內存分配不同。

至於類比:您可能已經到達牆的盡頭,因此不會傷到頭部,但是您不在屋內,也不會把錢包留在那里。

例如,這條線最終將指向某個地方:

sro->dwMem3 = 77; 

問題是:這是否在有效的程序空間內? 如果是這樣,則不會發生任何錯誤,但這並不意味着它很好。 您可能正在其他地方更改變量,從而導致無法預測的結果。

一個例子:

平台1:

| 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的其他說明,請參見:cplusplus.com有什么問題?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM