You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中存储双指针的vector迭代时元素值异常变化问题求助

嘿,我来帮你捋捋这个vector的问题~

问题根源

你遇到的核心问题其实是存储了同一个局部变量的地址,导致所有vector元素都指向同一个地方。

看你这段代码:

TreeNode* tmp; 
vertexQueue.push(Tree); 
while (!vertexQueue.empty()) { 
    tmp = vertexQueue.front(); 
    vertexQueue.pop(); 
    vertexVector.emplace_back(&tmp); 
    // ... 输出逻辑
}

这里的tmp是在循环外面定义的单个指针变量,整个循环过程中它的内存地址是固定不变的。每次循环你只是把tmp的值更新成队列弹出的新节点,但&tmp永远指向同一个内存位置。所以vertexVector里的所有TreeNode**元素,本质上都指向同一个tmp变量。当你下次循环更新tmp的值时,所有通过vector元素解引用得到的结果自然都会跟着变——因为它们都是在访问同一个tmp呀!

两种解决思路

根据你的需求,这里有两种常用的修正方式:

思路1:直接存储TreeNode*(推荐,最简单)

如果你的场景不需要二级指针,直接把vector的类型改成std::vector<TreeNode*>就搞定了:

std::queue<TreeNode*> vertexQueue; 
std::vector<TreeNode*> vertexVector; // 改成存储一级指针
TreeNode* tmp; 
vertexQueue.push(Tree); 
while (!vertexQueue.empty()) { 
    tmp = vertexQueue.front(); 
    vertexQueue.pop(); 
    vertexVector.push_back(tmp); // 直接存节点指针
    // 输出逻辑调整下:
    for (int i = 0; i < vertexVector.size(); i++) { 
        std::cout << vertexVector[i]->info.weigth << ' '; 
    } 
    std::cout << std::endl; 
    if (!isLeave(tmp)) { 
        vertexQueue.push(tmp->leftBranch); 
        vertexQueue.push(tmp->rigthBranch); 
    } 
}

这样每个vector元素都是独立的节点指针,指向队列中弹出的不同节点,再也不会出现全部同步变化的问题了。

思路2:必须用二级指针的场景(谨慎使用)

如果你确实需要用TreeNode**类型的vector,那得给每个节点分配独立的一级指针存储空间,不能复用同一个tmp:

std::queue<TreeNode*> vertexQueue; 
std::vector<TreeNode**> vertexVector; 
vertexQueue.push(Tree); 
while (!vertexQueue.empty()) { 
    // 把tmp移到循环里,每次创建新的指针变量
    TreeNode* tmp = vertexQueue.front(); 
    vertexQueue.pop(); 
    vertexVector.emplace_back(&tmp); 
    // 输出逻辑不变
    for (int i = 0; i < vertexVector.size(); i++) { 
        std::cout << (*vertexVector[i])->info.weigth << ' '; 
    } 
    std::cout << std::endl; 
    if (!isLeave(tmp)) { 
        vertexQueue.push(tmp->leftBranch); 
        vertexQueue.push(tmp->rigthBranch); 
    } 
}

⚠️ 注意:这种方式里循环内的tmp是栈上的局部变量,循环结束后这个变量就销毁了,后续再访问vector里的指针会触发未定义行为。如果要安全使用,得用动态分配的指针:

std::queue<TreeNode*> vertexQueue; 
std::vector<TreeNode**> vertexVector; 
vertexQueue.push(Tree); 
while (!vertexQueue.empty()) { 
    // 动态分配一级指针
    TreeNode** tmpPtr = new TreeNode*; 
    *tmpPtr = vertexQueue.front(); 
    vertexQueue.pop(); 
    vertexVector.push_back(tmpPtr); 
    // 输出逻辑调整下:
    for (int i = 0; i < vertexVector.size(); i++) { 
        std::cout << (*(*vertexVector[i]))->info.weigth << ' '; 
    } 
    std::cout << std::endl; 
    if (!isLeave(*tmpPtr)) { 
        vertexQueue.push((*tmpPtr)->leftBranch); 
        vertexQueue.push((*tmpPtr)->rigthBranch); 
    } 
}
// 记得最后释放内存,避免泄漏
for (auto ptr : vertexVector) {
    delete ptr;
}

但这种方式会增加内存管理的复杂度,所以没有特殊需求的话,优先选思路1就好。

内容的提问来源于stack exchange,提问作者Gleb Bessudnov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:42:37