[英]Buffer overrun with STL vector
我正在將一個 STL 向量的內容復制到另一個。 程序是這樣的
std::vector<uint_8> l_destVector(100); //Just for illustration let us take the size as 100.
std::vector<uint_8> l_sourceVector; //Let us assume that source vector is already populated.
memcpy( l_destVector.data(), l_sourceVector.data(), l_sourceVector.size() );
上面的例子非常簡單,但在我的實際代碼中,目標向量的大小是動態計算的。 此外,源向量正在動態填充,從而可以擁有不同長度的數據。 因此,它增加了緩沖區溢出的機會。
我面臨的問題是,當緩沖區溢出時,我的程序不會在memcpy
點崩潰,但稍后會使其難以調試。
我們如何解釋這種行為?
/***************************************************** ****************************************************** ***/ 根據回復,我正在編輯問題以使我的擔憂更易於理解。
所以,這是一個遺留代碼,有很多地方已經使用 memcpy 復制了 vector,我們不打算更改現有代碼。 我在這里主要關心的是“memcpy 不應該保證立即崩潰,如果不是為什么?” ,我會老實承認,這不是很好寫的代碼。
實際使用的簡要說明如下。
在下面的方法中, i_DDRSPDBuffer 和 i_dataDQBuffer 是根據調用方法中的一些邏輯生成的。
o_dataBuffer 被分配了一個內存空間,該空間足以從兩個輸入緩沖區中獲取數據,但是調用 updateSPDDataToRecordPerDimm 的方法中的一些最近更改導致其中一個流溢出。
typedef std::vector<uint8_t> DataBufferHndl;
errHdl_t updateSPDDataToRecordPerDimm(
dimmContainerIterator_t i_spdMmap,
const DataBufferHndl & i_DDRSPDBuffer,
const DataBufferHndl & i_dataDQBuffer,
DataBufferHndl & o_dataBuffer)
{
uint16_t l_dimmSPDBytes = (*i_spdMmap).second.dimmSpdBytes;
// Get the Data Buffer Handle for the input and output vectors
uint8_t * l_pOutLDimmSPDData = o_dataBuffer.data();
const uint8_t * l_pInDDRSPDData = i_DDRSPDBuffer.data();
const uint8_t * l_pInDQData = i_dataDQBuffer.data();
memcpy(l_pOutLDimmSPDData, l_pInDDRSPDData, l_dimmSPDBytes);
memcpy(l_pOutLDimmSPDData + l_dimmSPDBytes,
l_pInDQData, LDIMM_DQ_DATA_BYTES);
memcpy(l_pOutLDimmSPDData ,
l_pInDQData, LDIMM_DQ_DATA_BYTES); ====> Expecting the crash here but the crash happens some where after the method updateSPDDataToRecordPerDimm returns.
}
它不必崩潰,這是未定義的行為。
如果您在調試模式下使用std::copy
代替std::vector<uint_8>::iterator
s,您可能會遇到一個會捕獲它的斷言。
它不會在 memcpy 的那一刻崩潰,因為您“僅”覆蓋了分配的向量后面的內存。 只要您的程序不從損壞的內存中讀取並使用數據,您的程序就會繼續運行。
如前所述,使用 memcpy 不是復制 stl 容器內容的推薦方法。 你會在安全的一邊
std::copy std::vector::assign
在這兩種情況下,您還將獲得上述迭代器調試,這將在接近錯誤實際所在的位置觸發。
不要那樣做! 它最終會咬你。
使用std::copy
和output_iterator
,或者因為您知道目標的resize
將向量resize
為正確的大小或創建正確大小的向量並將內容直接輸入管道,或者簡單地使用賦值運算符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.