Memory management 为什么使用STL std::vector作为块变量会导致内存损坏?

Memory management 为什么使用STL std::vector作为块变量会导致内存损坏?,memory-management,vector,block,objective-c++,vmat,Memory Management,Vector,Block,Objective C++,Vmat,经过一段时间和努力,我已经在我的代码中找到了这个函数的内存崩溃错误。我通过将两个uu块向量变量替换为堆栈分配数组的组合来提供存储,并使用{klist | dlist}Ptr变量来允许块内的代码访问数组(见下面的推荐代码),从而停止了内存崩溃。这使我相当确信,使用块向量确实有问题 void traceTree(Matrix<double> Z, double s[3], int k, unsigned int depth) { int m = Z.size(1) + 1;

经过一段时间和努力,我已经在我的代码中找到了这个函数的内存崩溃错误。我通过将两个
uu块向量
变量替换为堆栈分配数组的组合来提供存储,并使用
{klist | dlist}Ptr
变量来允许块内的代码访问数组(见下面的推荐代码),从而停止了内存崩溃。这使我相当确信,使用块向量确实有问题

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;
    }
}
void
traceTree(矩阵Z,双s[3],整数k,无符号整数深度)
{
int m=Z.尺寸(1)+1;
__块向量klist(m,0);
//int-klist[m];int*klistPtr=klist;
//klist[0]=k;
__块向量数据列表(1,深度);
//int-dlist[depth];int*dlistPtr=dlist;
//dlist[0]=深度;
__块int topk=0;
int currk=0;
void(^子树)(int i)=^(int i){
如果(i>m){//如果它不是一片叶子。。。
topk+=1;
klist[topk]=i-m;
dlist[topk]=深度-1;
}
};
while(currk 0){
子树(Z[{ 0,k}]);/ /考虑左子树
子树(Z[{ 1,k}]);/ /考虑右子树
}
currk+=1;
}
}
[我应该指出,这是一个纯粹的迭代算法;没有递归。块的存在只是为了避免重复处理左右子树所需的代码。]


显而易见的问题是,为什么STL
vector
对象会导致内存损坏?他们甚至不做任何动态调整大小……它不支持使用C++对象作为< C++ >块> <代码>变量?< /p> < P> C++对象被允许作为<代码>×块Bux/Cux>变量(尽管我个人建议在编写C++时使用lambda,但是没有太多的理由使用纯C++中的块)。

<代码>块-< /Calp> C++变量是使用复制构造函数复制的(参见块编程主题)。如果堆栈太深(这与“内存损坏”症状相匹配),则可能是由于大型堆栈变量的副本太多而导致堆栈溢出


但是,我还是推荐LAMBDAS而不是C++的块;有关更多讨论,请参见。

除非是打字错误,否则我认为您对
dlist
的初始化与数组不同:
向量dlist(1,深度)生成长度为1的向量,而不是深度。这可能会导致越界


通过使用
dlist.at(currk)
而不是
dlist[currk]
进行读写操作,您可以随时防止访问超出范围的向量元素。

您能显示正在崩溃的代码吗?在显示其他代码时,不可能理解您所询问的内容。您可以
int*klistPtr=klist如果
klist
是一个
向量
,该如何工作?在代码中,您的块捕获的是
klistPtr
dlistPtr
,而不是
向量;我已经按照你的建议编辑了这个问题;它以迭代方式对树进行下降,基本上使用
klist
dlist
作为递归算法在堆栈上需要的存储。您关于C++ LAMBDAS的观点是一个很好的观点,但我仍然想知道代码中使用块的情况。(你不能通过GCD来发送C++ lambda;我在这个算法中没有这样做,但是我会在其他代码中使用这个习惯用法。)