經過一段時間和努力,我已經在我的代碼中追蹤了這個函數中的一個內存粉碎錯誤。我通過用堆棧分配數組的組合來替代兩個__block vector<int>
變量以提供存儲和{klist|dlist}Ptr
變量以允許塊內的代碼訪問數組(參見下面的推薦代碼)來停止內存粉碎。這使我相當確信這確實是使用__block vector<int>
這是有問題的。爲什麼使用STL std :: vector作爲__block變量導致內存損壞?
void
traceTree(Matrix<double> Z, double s[3], int k, unsigned int depth)
{
int m = Z.size(1) + 1;
__block vector<int> klist(m, 0);
// int klist[m]; int * klistPtr = klist;
// klist[0] = k;
__block vector<int> dlist(1, depth);
// int dlist[depth]; int * dlistPtr = dlist;
// dlist[0] = depth;
__block int topk = 0;
int currk = 0;
void (^ subtree)(int i) = ^(int i) {
if (i > m) { // If it's not a leaf...
topk += 1;
klist[topk] = i - m;
dlist[topk] = depth - 1;
}
};
while (currk <= topk) {
k = klist[currk];
depth = dlist[currk];
s[0] += Z[{2,k}]; // Sum of the edge lengths so far
s[1] += Z[{2,k}] * Z[{2,k}]; // ... and the sum of the squares
s[2] += 1; // ... and the count of the edges
if (depth > 0) {
subtree(Z[{0,k}]); // Consider left subtree
subtree(Z[{1,k}]); // Consider right subtree
}
currk += 1;
}
}
[我應該指出,這是一個純粹的迭代算法;沒有遞歸。該塊僅用於避免重複處理左側和右側子樹所需的代碼。]
顯而易見的問題是,爲什麼STL vector
對象在這裏導致內存損壞?他們甚至沒有做任何動態的調整大小......是否僅僅不支持使用C++對象作爲__block
變量?
你可以只顯示崩潰的代碼嗎?當您顯示其他代碼時,無法理解您所問的內容。你做'int * klistPtr = klist;'當'klist'是一個'vector'時會怎麼樣?在你的代碼中你的塊正在捕獲'klistPtr'和'dlistPtr',而不是'vector'。 –
newacct
2013-04-08 05:47:27
好點;我按照你的建議編輯了這個問題。 – 2013-04-08 11:59:04