簡體   English   中英

緩沖區溢出與 STL 向量

[英]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::copyoutput_iterator ,或者因為您知道目標的resize將向量resize為正確的大小或創建正確大小的向量並將內容直接輸入管道,或者簡單地使用賦值運算符。

暫無
暫無

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

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