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

C++二维vector实现好友关系类时出现内存访问错误

问题分析与修复:好友关系类的内存访问错误

问题描述

我尝试用C++编写一个表示人群好友关系的类,每个人对应二维vector的一行,行内元素代表该人的好友(好友关系为双向)。编写的代码如下:

class Friends {
public:
    Friends(int n);
// Creates a set of n people, no one knows each other.
    bool knows(int a, int b);
// returns true if the 2 people know each other 
    void getToKnow(int a, int b);
// Person a & b meet.
    void mutualFriends(int a, int b);
// cout's the mutual friends of person a & b
    void meeting(int a);
//all friends of person a also become friends
    int max();
//return the person with the highest number of friends

private:
    vector<vector<int>> friends;
};

Friends::Friends(int n) {
    vector<vector<int>> friends;
}

bool Friends::knows(int a, int b) {
    for(int i=0; i<friends[a].size(); i++) {
        if (friends[a][i]==b) {
            return true;
        }
    }
    return false;
}

void Friends::getToKnow(int a, int b) {
    friends[a].push_back(b);
    friends[b].push_back(a);
}

void Friends::mutualFriends(int a, int b) {
    for (int i=0; i<friends[a].size(); i++) {
        for (int j=0; j<friends[b].size(); j++) {
            if (friends[a][i]==friends[b][j])
                cout << friends[a][i] <<", ";
        }
    }
}

void Friends::meeting(int a) {
    for (int i=0; i<friends[a].size(); i++) {
        for(int j=0; j<friends[a].size();j++) {
            if(i!=j && i!=a && j!=a) {
                getToKnow(i,j);
            }
        }
    }
}

int Friends::max() {
    int maks = 0;
    for (int i=0; i<friends[i].size(); i++) {
      if (friends[i].size()<friends[i+1].size())
          maks = i;
    }
    return maks;
}

int main() {
    Friends f1 (4);
    f1.getToKnow(1,3);
}

但每次尝试向vector中添加元素(例如调用getToKnow函数)时,程序触发错误:Thread 1: EXC_BAD_ACCESS (code=1, address=0x20),错误指向friends[a].push_back(b);和friends[b].push_back(a);两行。我不清楚问题所在,也不确定是否正确使用了二维vector,希望得到帮助。


核心错误原因

构造函数中重新定义了局部的vector<vector<int>> friends;,这会遮蔽类的成员变量friends,导致成员变量始终是空的二维vector。当调用getToKnow访问friends[a]时,a(比如示例中的1)超出了空vector的索引范围,直接触发内存访问错误。

其他次要问题

  1. 缺乏索引合法性检查:所有涉及人员编号的函数都没有验证参数是否在0到n-1范围内,容易触发越界。
  2. 重复添加好友:getToKnow未检查两人是否已成为好友,会导致同一好友被多次添加到列表中。
  3. meeting函数逻辑错误:循环变量i、j是friends[a]的索引,而非人员编号,应该使用friends[a][i]和friends[a][j]获取好友的实际编号。
  4. max函数逻辑错误:循环条件错误,应该遍历所有人员(0到friends.size()-1),而非friends[i].size();同时比较逻辑会遗漏最后一个元素,还可能触发i+1越界。
  5. 头文件缺失:代码使用了vector和cout,但未包含<vector>和<iostream>头文件,编译会报错。

修正后的完整代码

#include <vector>
#include <iostream>
#include <algorithm>

using namespace std;

class Friends {
public:
    Friends(int n);
    bool knows(int a, int b);
    void getToKnow(int a, int b);
    void mutualFriends(int a, int b);
    void meeting(int a);
    int max();

private:
    vector<vector<int>> friends;
    bool isValidPerson(int idx);
};

Friends::Friends(int n) {
    friends.resize(n);
}

bool Friends::isValidPerson(int idx) {
    return idx >= 0 && idx < friends.size();
}

bool Friends::knows(int a, int b) {
    if (!isValidPerson(a) || !isValidPerson(b)) return false;
    return find(friends[a].begin(), friends[a].end(), b) != friends[a].end();
}

void Friends::getToKnow(int a, int b) {
    if (!isValidPerson(a) || !isValidPerson(b) || a == b) return;
    if (!knows(a, b)) {
        friends[a].push_back(b);
        friends[b].push_back(a);
    }
}

void Friends::mutualFriends(int a, int b) {
    if (!isValidPerson(a) || !isValidPerson(b)) return;
    for (int friendA : friends[a]) {
        if (knows(b, friendA)) {
            cout << friendA << ", ";
        }
    }
    cout << endl;
}

void Friends::meeting(int a) {
    if (!isValidPerson(a)) return;
    const vector<int>& aFriends = friends[a];
    for (size_t i = 0; i < aFriends.size(); ++i) {
        for (size_t j = i + 1; j < aFriends.size(); ++j) {
            getToKnow(aFriends[i], aFriends[j]);
        }
    }
}

int Friends::max() {
    if (friends.empty()) return -1;
    int maxIdx = 0;
    size_t maxCount = friends[0].size();
    for (size_t i = 1; i < friends.size(); ++i) {
        if (friends[i].size() > maxCount) {
            maxCount = friends[i].size();
            maxIdx = i;
        }
    }
    return maxIdx;
}

int main() {
    Friends f1(4);
    f1.getToKnow(1, 3);
    f1.getToKnow(1, 0);
    f1.getToKnow(3, 0);
    
    cout << "Mutual friends of 1 and 3: ";
    f1.mutualFriends(1, 3);
    
    f1.meeting(1);
    
    cout << "Person with most friends: " << f1.max() << endl;
}

关键修复说明

  1. 初始化成员变量:构造函数改用friends.resize(n)创建n个空的子vector,对应n个人的好友列表。
  2. 合法性检查:添加isValidPerson辅助函数,统一验证人员编号的有效性,避免越界访问。
  3. 避免重复添加:getToKnow先调用knows检查关系,防止同一好友被多次添加。
  4. 修正meeting逻辑:使用好友的实际编号而非索引进行操作,同时优化为只遍历i<j的配对,避免重复调用getToKnow。
  5. 修正max函数:遍历所有人员,正确比较好友数量,返回好友最多的人员编号。
  6. 补充头文件:添加<vector>、<iostream>和<algorithm>头文件,确保编译通过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 02:35:20