繁体   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