2009-01-11 48 views
4

我遇到了一個非常奇怪的錯誤,我希望有人能解釋。我有一個簡單std::vector<V3x>,其中V3x是一個三維矢量下面的代碼導致std::length_error引發異常(線性代數的那種。):std :: vector堆棧幀之間的C++參數的值變化

std::vector<V3x> vertices; 
int vertexCount = computeVertexCount(); 
vertices.resize(vertexCount); // throws std::length_error 

我已驗證computeVertexCount()返回35一個值,該值遠遠低於vector::max_size(),所以它沒有辦法要求太多的內存。

我將異常向下追溯到std::vector的定義,以下兩個函數。

void resize(size_type _Newsize, _Ty _Val) 
    { // determine new length, padding with _Val elements as needed 
    if (size() < _Newsize) 
     // NOTE: here, _Newsize - size() = 35 
     _Insert_n(end(), _Newsize - size(), _Val); 
    else if (_Newsize < size()) 
     erase(begin() + _Newsize, end()); 
    } 

void _Insert_n(const_iterator _Where, 
    size_type _Count, const _Ty& _Val) 
    { // insert _Count * _Val at _Where 
     // NOTE: here, _Count = 3435973836 
     ... 
    } 

所以當_Count參數resize()_Insert_n()之間傳遞,價值的變化,從35到3435973836.我假設的內存有時會損壞,但我不知道怎麼會是。

對於更多的情況下,如果它是問題的一部分,此代碼位於我從Softimage XSI加載的.dll插件中。

有誰知道什麼可能會導致這樣的事情發生?

編輯:解

nobugz,我可以吻你。

由於VS2008中的_HAS_ITERATOR_DEBUGGING,std :: vector的大小在我的.dll文件中發生了變化。搜索使我someone with the same problem,它是由添加在我的項目的頂部以下固定:

// fix stack corruption errors caused by VS2008 
#define _HAS_ITERATOR_DEBUGGING 0 
#define _SECURE_SCL 0 
+0

是性病::矢量頂點;真的是一個局部變量?否則,它可能很好,因爲它尚未創建(因爲靜態初始化失敗) – 2009-01-11 17:52:08

+0

是否vertices.resize(vertexCount);需要第二個參數? – 2009-01-11 19:48:57

回答

20

3435973836的值很重要。在十六進制中,這是0xcccccccc。這是堆棧幀初始化代碼在調試模式下分配給本地變量的值。當你在調試時看到它,你會說「啊,變量未初始化」。也許這會讓你更接近解決這個問題。

您提到DLL。這也是相關的。迭代器的調試可能會讓你陷入困境,你不能將代碼關閉,而代碼沒有關閉。由於DLL可能是沒有它編譯,嘗試的#define _HAS_ITERATOR_DEBUGGING 0

0

發佈的代碼是正確的,你可以假設的std ::向量沒有錯誤。在最純粹的可能環境中複製異常(新的空白項目)。在ComputeVertexCount()中可能是愚蠢的like this

0

我建議查看爲相關項目配置的C++選項。確保它們都共享相同的對齊和運行時設置。您是否在構建涉及的.DLL?

2

每當參數或局部變量意外改變時,很有可能是由於堆棧損壞。只要使用未初始化的局部變量或將數據存儲在分配給本地字符串或數組的內存之外,就會發生這種情況。

一個簡單的方法來調試這一點:

  1. 加載程序進入調試器。
  2. 在違規函數的第一行代碼中插入一個斷點。
  3. 執行程序,直到它遇到斷點。
  4. 對意外改變的變量設置監視。
  5. 逐步完成功能,直到發生意外更改。

當寫入未分配(或錯誤分配)的內存時,將發生更改。寫的目標是違規變量。