2013-03-01 38 views
1

我開發的C++程序,當我運行此代碼會遇到這樣的錯誤:使兩個字節變爲短時發生堆損壞。 C++

short readshort() { 
    short val=0; 
    (&val)[1]=data.front(); data.pop_front(); 
    (&val)[0]=data.front(); data.pop_front(); 
    return val; 
} 

這是錯誤我得到:

Run-Time Check Failure #2 - Stack around the variable 'val' was corrupted. 

我要提現,即「數據」用std :: list數據定義;

我想我知道什麼是問題,但我想不出一個簡單的解決方案。我認爲這個錯誤是由存儲在堆棧中的「val」導致的,而不是作爲指針。當我嘗試通過「val」訪問數據指針時,出現此錯誤。

我想過被分配「VAL」該解決方案是這樣的:

short readshort() { 
    short* val=new short; 
    val[1]=data.front(); data.pop_front(); 
    val[0]=data.front(); data.pop_front(); 
    return *val; 
} 

,但我看不到的方式來刪除「VAL」一旦我回來了它,而無需將其刪除的功能外每次。 有沒有辦法可以在C++中完成內存泄漏?我沒有看到任何人在之前使用「(& val)[1]」將變量類型(例如,短)分割成字節,並且想知道是否這是因爲它引起了許多問題,或者它只是不知道方法?

現在回到真正的問題,我怎樣才能使這兩個字節爲短(或大數據類型)?有沒有比我嘗試過的更好的方法呢?

最後一件事,我知道java有一個自動垃圾回收器,可以自動清理內存泄漏。 C++是否提供相同類型的設備?我聽到有關的財產以後智能指針,但我不知道他們是什麼;)

回答

2

這是安全和簡單:

int16_t readshort() 
{ 
    union { int16_t s; char val[2]; } u; 
    u.val[1]=data.front(); data.pop_front(); 
    u.val[0]=data.front(); data.pop_front(); 
    return *(int16_t*)u.val; 
} 
+0

這真的很安全嗎?如果該數組最終不是16位對齊的呢?也許它必須是 - 我恐怕不是C++專家。 – 2013-03-01 23:12:03

+0

@Carl:可能對自動變量不安全。從來沒有遇到過一個沒有的系統。其他:「對於char和 無符號字符的數組,新表達式的結果與 分配函數返回的地址之間的差值應爲任何對象類型的最嚴格基本對齊要求(3.11)的整數倍其大小不大於正在創建的數組的大小[注意:對數組分配開銷的這種限制允許分配 字符數組的常見方式,其中將放置其他類型的對象。[尾註]「 – 2013-03-01 23:18:12

+0

@卡爾:已更新以保證對齊。 – 2013-03-01 23:19:09

0

(&val)[1]訪問你沒有分配的內存。巴姆 - 未定義的行爲。你的兩個例子都有同樣的問題。

如果要拆分這樣的字節,你需要使用char指針訪問單個字節:

short readshort() { 
    short val=0; 
    ((char *)&val)[1]=data.front(); data.pop_front(); 
    ((char *)&val)[0]=data.front(); data.pop_front(); 
    return val; 
} 

此代碼是真的很醜陋,但。爲什麼不乾脆:

short readshort() { 
    short val=0; 
    val = data.front() << 8; data.pop_front(); 
    val |= data.front() << 0; data.pop_front(); 
    return val; 
} 

根據字節序,您可能需要交換80出現的位置。

+0

也非常有幫助的代碼,謝謝卡爾:) – 2013-03-02 17:30:55

1

(&val)[1]=data.front()做錯誤(&val)[1]您正在將下一個存儲位置寫入val未定義。

(&val)[i]意味着*(&val + i)
(&val)[0]意味着*(&val + 0) = *(&val)這一優良
(&val)[1]意味着*(&val + 1) =但是因爲你的聲明是short val所以我們只能訪問VAL的位置,這是錯誤。

+----+----+----+---+---+----+----+----+---+----+ 
|val  |  | 
+----+----+----+---+---+----+----+----+---+---+----+ 
201 202 203 204 205 206 207 208 209 210 211 
^  ^
    |   | 
&val   (&val + 1) 
       its not defined. 

您可以使用像@Carl Norum建議的tyoecase。我只是寫第二種形式來做到這一點。

char *ptr = (char*)&val; 

ptr[0]=data.front() 
ptr[1]=data.front() 

但是,如果您需要val作爲簡短,並希望訪問個別字節。我想建議union

union Data{ 
short val; 
char ch1; 
char ch2; 
}; 

union Data d; 

d.ch1 = data.front() 
d.ch2 = data.front() 
1

你需要投你的指針爲char *。

((char *)(&val))[1]=data.front(); 
((char *)(&val))[0]=data.front(); 

我想你的情況:(& VAL)[1] = data.front();你寫數據到第二短。結果你會得到錯誤。