我的指针问题似乎指向了错误的地址。我在League类中有一个函数来创建日程表:
void League::CreateSchedule()
{
for (int i = 0; i < allTeamsInLeague.size(); i++)
{
int tempDay = startingDay, tempMonth = startingMonth, tempYear = Time::GetInstance().GetYear();
for (int y = 0; y < allTeamsInLeague.size(); y++)
{
if (i != y)
{
allNotPlayedLeagueMatches.push_back(NotPlayedMatch(allTeamsInLeague[i], allTeamsInLeague[y], tempDay, tempMonth, tempYear));
allTeamsInLeague[i]->GetMyMatches().push_back(&allNotPlayedLeagueMatches[allNotPlayedLeagueMatches.size() - 1]);
allTeamsInLeague[y]->GetMyMatches().push_back(&allNotPlayedLeagueMatches[allNotPlayedLeagueMatches.size() - 1]);
std::cout <<"Size of allNotPlayedLeagMatches: " << allNotPlayedLeagueMatches.size() << std::endl;
}
}
}
std::cout <<"League shedule done!" <<std::endl;
}
它将在allNotPlayedLeagueMatches向量(NotPlayedLeagueMatches)中创建的匹配地址添加到类Team的向量myMatches(向量(Match *),其中Match是纯抽象类)。
std::vector<Match*> &Team::GetMyMatches()
{
return myMatches;
}
然后当我尝试输出球队的比赛时,它会在显示myMatches [0]时崩溃,但是在显示myMatches [1]时它并没有崩溃。我试图使用调试器来解决这个问题,它说无法读取myMatches [0]的内存。
这是League.h文件:
#pragma once
#include "PlayedMatch.h"
#include "Time.h"
#include <vector>
#include <iostream>
class League
{
public:
//Default Constructor
League();
//Overloaded Constructor
League(std::string name, int startingDay, int startingMonth);
//Destructor
~League();
std::vector<Team*> &GetAllTeamsInLeague();
void CreateSchedule();
private:
std::vector<Team*> allTeamsInLeague;
std::string name;
int startingDay, startingMonth;
std::vector<NotPlayedMatch> allNotPlayedLeagueMatches;
std::vector<PlayedMatch> allPlayedLeagueMatches;
};
League.cpp:
#include "League.h"
League::League()
{
name = "";
startingDay = 1;
startingMonth = 1;
}
League::~League()
{
}
League::League(std::string name, int startingDay, int startingMonth)
{
this->name = name;
this->startingDay = startingDay;
this->startingMonth = startingMonth;
}
std::vector<Team*> &League::GetAllTeamsInLeague()
{
return allTeamsInLeague;
}
void League::CreateSchedule()
{
for (int i = 0; i < allTeamsInLeague.size(); i++)
{
int tempDay = startingDay, tempMonth = startingMonth, tempYear =Time::GetInstance().GetYear();
for (int y = 0; y < allTeamsInLeague.size(); y++)
{
if (i != y)
{
allNotPlayedLeagueMatches.push_back(NotPlayedMatch(allTeamsInLeague[i], allTeamsInLeague[y], tempDay, tempMonth, tempYear));
allTeamsInLeague[i]->GetMyMatches().push_back(&allNotPlayedLeagueMatches[allNotPlayedLeagueMatches.size() - 1]);
allTeamsInLeague[y]->GetMyMatches().push_back(&allNotPlayedLeagueMatches[allNotPlayedLeagueMatches.size() - 1]);
std::cout <<"Size of allNotPlayedLeagMatches: " << allNotPlayedLeagueMatches.size() << std::endl;
}
}
}
std::cout <<"League shedule done!" <<std::endl;
}
Team.h:
#ifndef Team_H
#define Team_H
#include <iostream>
#include <string>
#include <vector>
#include "Match.h"
using namespace std;
class Team
{
public:
//Default Constructor
Team();
//Overloaded Constructor string name, int defense, int attack
Team(string, int, int, int, int);
//Destructor
~Team();
void ShowTeamCharacteristics();
//shows the team characteristics(defence, attack, name...)
int GetAttack();
//Returns team's attack ability
int GetDefense();
//Returns team's defence ability
int GetLeagueX();
//sets in which country the team is
int GetLeagueY();
//sets in which league the team is
void ShowCalendar();
string GetName();
//Returns team's name
void SetAttack(int);
//sets the new value to the current attack
void SetDefense(int);
//sets the new value to the current defense
void SetName(string);
//sets the new value to the current name
void SetLeagueX(int);
//sets in which country the team is
void SetLeagueY(int);
//sets in which league the team is
std::vector<Match*> &GetMyMatches();
private:
int defense, attack; // 100 - defense = chance to concede a goal, attack / 1.5 = chance to score a goal
string name; // The name of the team
int leagueX, leagueY;
int points;
std::vector<Match*> myMatches;
};
#endif
Team.cpp:
#include "Team.h"
Team::Team()
{
name = "";
attack = 0;
defense = 0;
leagueX = 0;
leagueY = 0;
points = 0;
}
Team::Team(string name, int defense, int attack, int leagueX, int leagueY)
{
this->name = name;
this->defense = defense;
this->attack = attack;
this->leagueX = leagueX;
this->leagueY = leagueY;
points = 0;
}
Team::~Team()
{
}
void Team::ShowCalendar()
{
for (int i = 0; i < myMatches.size(); i++)
{
myMatches[i]->ShowMatchDetails();
}
}
std::vector<Match*> &Team::GetMyMatches()
{
return myMatches;
}
void Team::ShowTeamCharacteristics()
{
system("cls");
cout <<"Name: " << name << endl <<
"Attack: " << attack << endl <<
"Defense: " << defense << endl;
}
int Team::GetAttack()
{
return attack;
}
int Team::GetDefense()
{
return defense;
}
int Team::GetLeagueX()
{
return leagueX;
}
int Team::GetLeagueY()
{
return leagueY;
}
string Team::GetName()
{
return name;
}
void Team::SetAttack(int attack)
{
this->attack = attack;
}
void Team::SetDefense(int defense)
{
this->defense = defense;
}
void Team::SetName(string name)
{
this->name = name;
}
void Team::SetLeagueX(int num)
{
leagueX = num;
}
void Team::SetLeagueY(int num)
{
leagueY = num;
}
知道什么是错的吗?
答案 0 :(得分:2)
问题在于,当您添加其他元素时,allNotPlayedLeagueMatches
向量中的元素可能会被移动。
想象一下以下场景:将元素推送到向量。为矢量存储分配固定数量的存储器,并将对象放在那里。现在,您可以在内存中找到指向该位置的指针并将其存储在某处。
现在,您将其他元素推送到向量中,直到它的容量耗尽为止。因此,向量分配更大的内存部分,将所有元素复制到新的内存位置,然后释放原始存储。
问题是你的指针仍然指向旧位置,现在正悬空。只要没有人接触到该内存,取消引用指针仍然可以工作,但是你仍然有一个错误(取消引用悬空指针是未定义的行为)。
解决这个问题的一种方法是在插入所有元素后仅指向矢量元素。当然,这意味着您的向量必须在程序中的某个时刻被“冻结”,并且不允许对其进行更多更改。如果这不是一个选项,请考虑使用另一个不会在插入时移动对象的容器(如std::list
)。