【发布时间】:2013-04-07 21:42:51
【问题描述】:
经过一些时间和努力,我在我的代码中找到了这个函数的内存破坏错误。我通过将两个 __block vector<int> 变量替换为堆栈分配数组的组合来提供存储和一个 {klist|dlist}Ptr 变量以允许块内的代码访问数组,从而停止了内存粉碎(见下面的推荐代码)。这让我相当有信心,确实是使用__block vector<int> 有问题。
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<int>时,这将如何工作?在您的代码中,您的块正在捕获klistPtr和dlistPtr,而不是vector。 -
好点;我已按照您的建议编辑了问题。
标签: memory-management vector block objective-c++ vmat