簡體   English   中英

C ++中的指針對象

[英]Pointer object in C++

我有一個非常簡單的類,如下所示:

class CHeader
{
public:
  CHeader();
  ~CHeader();
  void SetCommand( const unsigned char cmd );
  void SetFlag( const unsigned char flag );
public:
  unsigned char iHeader[32];    
};

void CHeader::SetCommand( const unsigned char cmd )
{
    iHeader[0] = cmd;
}

void CHeader::SetFlag( const unsigned char flag )
{
    iHeader[1] = flag;
}

然后,我有一個方法,將指向CHeader的指針作為輸入,如下所示:

void updateHeader(CHeader *Hdr)
{

   unsigned char cmd = 'A';
   unsigned char flag = 'B';

   Hdr->SetCommand(cmd);
   Hdr->SetFlag(flag);
   ...
}

基本上,此方法只是將一些數組值設置為某個值。

然后,我創建一個指向類CHeader的對象的指針,並將其傳遞給updateHeader函數:

CHeader* hdr = new CHeader();
updateHeader(hdr);

這樣做時,程序在執行Hdr-> SetCommand(cmd)行時便崩潰了。 任何人看到問題,任何輸入將不勝感激

當您撞車時,就像犯罪調查員一樣:調查犯罪現場。

  • 您從環境中獲得的信息是什么(訪問沖突?任何調試消息?* Hdr處的內存是什么樣的?...)
  • 傳入的Hdr指針有效嗎?

然后使用邏輯推論,例如:

  • Hdr的取消引用導致訪問沖突
  • =>傳遞的Hdr指向無效的內存
  • =>內存以無效開頭(錯誤的指針傳入),或者內存無效(對象在傳入指針之前被刪除,或者有人在內存上繪畫)
  • ...

可能是SEGFAULTing。 檢查指針。

  • 您添加一些源代碼
  • 您對事物在另一台機器上運行的評論
  • 您使用術語“標志”和“ cmd”以及一些非常小的數據類型的事實

讓我假設目標計算機的容量非常有限,我建議測試new CHeader的結果的有效性:如果系統資源不足,則結果指針將不會引用有效內存。

您提供的代碼沒有錯。

輸入“ updateHeader”函數后,是否確定創建的指針具有相同的地址? 可以肯定的是,在new()記下地址之后,用已知的唯一值(例如0XDEAD)填充內存sizeof(CHeader),然后追溯到updateHeader函數,確保所有內容均相等。

除此之外,我想知道這是否是對齊問題。 我知道您使用的是8位值,但是請嘗試將數組更改為無符號整數或長整型,看看是否遇到相同的問題。 您在什么架構上運行它?

您的代碼看起來不錯。 我看到的唯一潛在問題是您在類中聲明了CHeader構造函數和析構函數,但未顯示任何一個的實現。 我想您只是省略了顯示這些內容,否則鏈接器應該抱怨(如果我在VC ++ 6中復制此項目,則構造函數會出現“無法解決的外部錯誤”。它也應該顯示相同的錯誤)析構函數,如果您有...刪除hdr; ...代碼中的語句)。

但是實際上沒有必要為類中聲明的每個方法都實現,除非方法實際上將要被調用(任何未實現的方法將被編譯器/鏈接器忽略(如果從未調用)。 當然,對於一個對象,在實例化該對象時必須調用其中一個構造函數-這就是如果您省略向類中添加任何構造函數的原因,則編譯器將為您創建默認構造函數的原因。 但是,如果不執行聲明的構造函數,則編譯器將上面的代碼編譯/鏈接將是一個嚴重的錯誤,因此,如果這是導致您出現問題的原因,我將感到非常驚訝。

但是,您描述的症狀絕對聽起來像是傳遞給updateHeader函數的'hdr'指針無效。 原因是在updateHeader函數調用之后第一次取消引用此指針是在... Hdr-> SetCommand(cmd);中。 ...通話(您說崩潰了)。

我只能想到這種無效指針的兩種可能情況:

a。)您的堆有問題,並且在創建“ hdr”對象時使用“ new”運算符分配內存失敗。 也許您的堆空間不足。 在某些嵌入式環境中,您可能還需要提供“新”和“刪除”運算符的“自定義”版本。 最簡單的檢查方法(您應該始終這樣做)是在分配后檢查指針的有效性:

CHeader* hdr = new CHeader();
if(hdr) {
    updateHeader(hdr);
}
else
    //handle or throw exception...

當“ new”失敗時,正常的行為實際上應該是引發異常-因此,以下代碼也可以滿足該要求:

try{
CHeader* hdr = new CHeader();
} catch(...) {
//handle or throw specific exception i.e. AfxThrowMemoryException() for MFC
}
if(hdr) {
updateHeader(hdr);
}
else
//handle or throw exception...
}

b。)您使用的是一些較舊的(可能是16位和/或嵌入式)環境,您可能需要在堆上創建的對象使用FAR指針(包括SEGMENT地址)。

我懷疑您需要提供有關環境以及編譯器的更多詳細信息,以獲得有關此問題的任何有用反饋。

暫無
暫無

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

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