在数据读入函数中将指针存储在vector中

Storing pointers in a vector in a data-read-in function

本文关键字:指针 存储 vector 函数 数据      更新时间:2023-10-16

我有一个包含联赛,球队和球员的文本文件,看起来像这样:

League: some league
Team:  some team
some players with name and strength
League: some other league

现在我用我的readin函数读取数据

#include "ReadIn.h"
#include "Player.h"
#include <deque>
#include <fstream>
#include <string>
#include <sstream>
#include <memory>
#include <iostream>

std::string zeile,word1, word2, sname, lname;
std::deque<Team*> Teamvector;
int str, a = 0, b = 0 , c = 0;
using namespace std;
void readin_fillVector(std::deque<Team> &v, std::deque<League> & w, std::vector<Player> u) {
    ifstream fin("C:\Users\david\Documents\Visual Studio 2013\Projects\Anstoss2014\Datenbank\test.txt");
    //Einlesen der Zeilen starten
    while (getline(fin, zeile))
    {
        fin >> word1;
        //find out if this line contains the team name or the players
        if (word1 == "Liga:"){
            getline(fin, word2);
            //deleting the empty space in front of the team name
            word2.erase(0, 1);
            w.push_back(League(word2, c));
            c++;
        }
        else if (word1 == "Verein:"){
            getline(fin, word2);
            //deleting the empty space in front of the team name
            word2.erase(0, 1);
            v.push_back(Team(word2, a));
            //League gets the new member ( the team which was read in the line before)
            w.back().AddTeam(&v.back());
            //Team gets an pointer to the league it plays in
            v.back().SetLeague(&w.back());
            a++;
        }
        else{
            fin >> lname >> str;
            Player* player = new Player();
            player->setinformation_(b, word1, lname, str, &v.back());
            u.push_back(*player);
            v.back().AddPlayer(player);
            //for (size_t f = 0; f < v.back().GetPlayerList().size(); f++)
            //{
            //  v.back().GetPlayerList()[f]->getinformation_();
            //}
            b++;
        }
        
    }
}

这是应该的,但我混淆了

这行
Player* player = new Player();

我读了很多关于指针的文章,有人说这个由new()创建的播放器应该被删除。第一个问题是:1。

但是如果我在函数中这样做,则存储在球队playervector中的球员信息将丢失。

2。我有boost可访问,我应该使用boost::ptr_vector之类的东西吗?

3。如果没有,我还能做些什么来避免内存泄漏?

编辑:

另一种方法是

Player player;
player.setinformation_(b, word1, lname, str, &v.back());
u.push_back(player);
v.back().AddPlayer(&player);

但是当函数返回teamvector时,玩家没有存储更多信息。

首先,按值传递std::vector<Player>。您可能打算通过引用传递它,否则您对它所做的任何更改都将丢失。

关于你的具体问题,你的"另一种方式"看起来几乎是正确的,但是你在teamvector中存储了一个指向本地player变量的指针。当本地player超出作用域时,该指针将悬空。你需要在播放器向量中存储一个指向播放器副本的指针,因为它拥有播放器。

然而,正如你所发现的,即使这也不会起作用,因为当玩家向量在push_back期间被重新分配时,指向向量元素的所有指针都将失效。你可以提前在玩家向量中设置reserve所需的所有空间,以确保不会发生重新分配,但你可能不知道reserve有多少空间。您可以使用不同的STL容器,如std::list,它承诺指针不会无效。但是如果你不想妥协你选择的容器,我建议你在堆上创建你的播放器对象,并使用智能指针来管理内存,无论是std::shared_ptr还是std::unique_ptr。所以函数原型看起来像:

in_fillVector(std::deque<Team> &v, std::deque<League> & w, std::vector<std::unique_ptr<Player>> &u) 

和添加球员看起来像:

auto player = std::unique_ptr<Player>(new Player());
player->setinformation_(b, word1, lname, str, &v.back());
v.back().AddPlayer(player.get());
u.push_back(std::move(player));