指向错误地址的指针?

时间:2013-12-05 16:39:36

标签: c++

我的指针问题似乎指向了错误的地址。我在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;
}

知道什么是错的吗?

1 个答案:

答案 0 :(得分:2)

问题在于,当您添加其他元素时,allNotPlayedLeagueMatches向量中的元素可能会被移动。

想象一下以下场景:将元素推送到向量。为矢量存储分配固定数量的存储器,并将对象放在那里。现在,您可以在内存中找到指向该位置的指针并将其存储在某处。

现在,您将其他元素推送到向量中,直到它的容量耗尽为止。因此,向量分配更大的内存部分,将所有元素复制到新的内存位置,然后释放原始存储。

问题是你的指针仍然指向旧位置,现在正悬空。只要没有人接触到该内存,取消引用指针仍然可以工作,但是你仍然有一个错误(取消引用悬空指针是未定义的行为)。

解决这个问题的一种方法是在插入所有元素后仅指向矢量元素。当然,这意味着您的向量必须在程序中的某个时刻被“冻结”,并且不允许对其进行更多更改。如果这不是一个选项,请考虑使用另一个不会在插入时移动对象的容器(如std::list)。