[英]Why I fail to compile VS2012 C++ code with boost 1.54 over win64?
[英]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_pValueChecks
與other.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.