簡體   English   中英

是什么導致在 64 位 VS2012 編譯環境中出現此緩沖區溢出警告?

[英]what is causing this buffer overrun warning over 64 bit VS2012 compile environment?

我有一個使用 VS2010 64 位環境編譯的工作應用程序 - 在嘗試將其遷移到 VS2012 編譯器 (C++11) 時,我收到 C6386 警告並且似乎無法找到根本原因:

這是產生警告的代碼片段:

Packet::Packet(const Packet& oOther)
{
   m_vData.assign(oOther.m_vData.begin(),oOther.m_vData.end());
   if(NULL != oOther.m_pValueChecks)
   {
      m_pValueChecks = new set<string>*[oOther.m_vData.size()];
      for(size_t i = 0; i < oOther.m_vData.size(); ++i)
      {

        if(NULL == oOther.m_pValueChecks[i])
        {
             m_pValueChecks[i] = NULL;
        }
        else
        {
/// compiler warns on the below line
             m_pValueChecks[i] = new set<string>(oOther.m_pValueChecks[i]->begin(), oOther.m_pValueChecks[i]->end());
        }
      }
   }
}

數據包類定義:

class Packet
{
public:
    Packet();
    Packet(const Packet&);

    .....

    vector<pair<string,pair<FieldType,Field> > > m_vData;
    set<string> ** m_pValueChecks;
}

產生的警告:

c:\\<my_path_and_file>(3331): warning C6386: Buffer overrun while writing to 'm_pValueChecks': the writable size is 'oOther.m_vData.public: unsigned __int64 __cdecl std::vector<struct std::pair<string,struct std::pair<enum Packet::FieldType,class Field> >,class std::allocator<struct std::pair<string,struct std::pair<enum Packet::FieldType,class Field> > > >::size(void)const ()*8' bytes, but '16' bytes might be written.: Lines: 3312, 3313, 3314, 3315, 3316, 3317, 3318, 3319, 3320, 3322, 3323, 3325, 3331, 3323, 3325, 3331

由於編譯環境是 64 位, oOther.m_vData.size()size_t類型,它是 64 位環境中的 64 位無符號整數,因此for循環在范圍上正確迭代,並且m_pValueChecks包含足夠的分配項以滿足那作業。

為什么會產生警告?

您似乎在一些地方將other.m_pValueChecksother.m_vData混合other.m_pValueChecks 由於數組大小不匹配,這可能會導致內存損壞。

與其使用這種可怕的雙指針方法,不如考慮將您的集合放入另一種容器類型中,讓語言安全地為您完成所有這些工作。

好的 - 繼續深入研究場景 - 我發現該項目包含 /analyze 開關,該開關強制 VS2012 的代碼分析選項始終運行。

刪除此開關時,上述(討厭的我同意)代碼編譯時沒有任何警告。

現在,由於此特定代碼在 VS2010 64 位環境下編譯時沒有警告,那么 VS2010 與 VS2012 代碼分析規則差異是警告的主要嫌疑人。

目前,我已經在遷移工作中克服了這個障礙,稍后我將嘗試繼續了解規則差異。 如果有人可以在上面遮光,最好把它貼在這里。

編輯:我發現代碼分析器在 VS2010 上不起作用 - 編譯器開關被忽略,這解釋了為什么編譯這段代碼。 無論如何,需要適當的重構。

編輯 2

伙計們,經過深思熟慮(近 6 個月),我終於找到了根本原因......

m_pValueChecks = new set<string>*[oOther.m_vData.size()];
for(size_t i = 0; i < oOther.m_vData.size(); ++i)
{

  if(NULL == oOther.m_pValueChecks[i])
  {
       m_pValueChecks[i] = NULL;
  }
  else
  {
      /// commpiler warns on the below line
      m_pValueChecks[i] = new set<string>(oOther.m_pValueChecks[i]->begin(), oOther.m_pValueChecks[i]->end());
  }
}

原因是for循環使用++i增加i索引,這意味着首先增加i變量,然后使用。

這意味着i變量有可能大於oOther.m_vData.size() ,這是m_pValueChecks分配數組的大小。

for floop 更改for for(size_t i = 0; i < oOther.m_vData.size(); i++)刪除了警告。

暫無
暫無

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

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