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

在for循环中访问结构体向量内的动态结构体向量触发访问违例

问题排查:访问违规错误分析

代码片段

struct cave{
    cave(std::string name, bool is_small, bool is_visited)
    :name{name}, is_small{is_small}, is_visited{is_visited}  {}
    
    std::string name{};
    std::vector<cave*> connections;
    bool is_small{};
    bool is_visited{};
};

cave* find_cave(std::vector<cave*> &v, std::string s){
    for (int i{}; i<v.size(); i++){
        if (v[i]->name==s) return v[i];
    }
    return v[0];
}

//v_temp 包含若干字符串
std::vector<std::string> v_temp;
std::vector<cave*> vec_2d;

for(int i=0; i<v_temp.size();i++){
    vec_2d.push_back(new cave(v_temp[i],islower(v_temp[i][0]),0));  
}

/*
添加洞穴间的连接逻辑,原本应该在循环内执行
vec_2d_temp 长度为2,包含两个字符串
*/
vec_2d[i]->connections.push_back(find_cave(vec_2d,vec_2d_temp[1]));
//或者
vec_2d[i]->connections.push_back(find_cave(vec_2d,vec_2d_temp[0]));

for (size_t i = 0; i < vec_2d.size(); i++) {
    if (vec_2d[i]->connections.size() < 2) {
        std::cout << "TEST: "<<vec_2d[i]->connections[0]->is_small << "\n";
    }
}

问题描述

运行上述代码时触发「Access violation reading location 0x00000000」错误,但单独访问vec_2d[0]->connections[0]->is_small时可正常运行,询问是否为作用域问题。

错误原因及解决方法

  1. 连接代码的索引越界问题
    你把添加连接的代码写在了填充vec_2d的for循环外面,此时循环变量i的值等于v_temp.size()(也就是vec_2d的元素总数)。而vec_2d的有效索引范围是0到vec_2d.size()-1,访问vec_2d[i]属于越界访问,会写入非法内存区域,导致后续出现不可预测的错误。
    解决:将添加连接的逻辑移到第一个for循环内部,或者确保i的取值在vec_2d的有效索引范围内。

  2. 空vector访问问题
    最后遍历的循环中,判断connections.size() < 2后直接访问connections[0],但如果某个cave的connections是空的(size() == 0),访问connections[0]会触发未定义行为,也就是你遇到的访问违规。
    解决:修改判断条件为connections.size() > 0,确保有元素时再访问:

    if (vec_2d[i]->connections.size() > 0) {
        std::cout << "TEST: "<<vec_2d[i]->connections[0]->is_small << "\n";
    }
    
  3. find_cave函数的潜在风险
    如果find_cave找不到指定名称的洞穴,直接返回v[0],但如果vec_2d为空(比如v_temp没有元素),v[0]也会导致越界访问。建议在函数开头先判断v是否为空,或者返回nullptr并在调用处处理:

    cave* find_cave(std::vector<cave*> &v, std::string s){
        if (v.empty()) return nullptr;
        for (size_t i{}; i<v.size(); i++){
            if (v[i]->name==s) return v[i];
        }
        return nullptr;
    }
    

    调用时检查返回值是否为nullptr,避免后续访问空指针。

总结

你的问题不是作用域问题,主要是索引越界访问和空vector元素访问导致的未定义行为,单独访问vec_2d[0]正常只是因为该元素的connections恰好有有效数据,其他元素则存在无效访问的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 08:55:31