我不明白多线程游戏中的对象不匹配

I don't understand the object mismatch in a multithreading game

我正在开发一款多线程游戏。它有 3 个 classes :

每个线程控制一个 Batiment 对象,一切似乎都很好,但是当我尝试输出游戏时,显示我的不同线程的 ID 号代表地图中的 Batiment,它没有不工作。它不会打印每个线程,它只会打印我在 main.cpp 中创建的最后一个 Batiment

我在上面待了 3 天...

这是我的文件:

main.cpp:

std::vector<Batiment> batiments;
for(int i = 0; i < nbrBatiments; i++){ //Ajout des Batiments sur le vecteur
        //Batiment temp = new Batiment(&carte, i);
        Batiment temp(&carte, i);
        batiments.push_back(temp);
    }
    for(int i = 0; i < nbrBatiments; i++){
        if ((rc = pthread_create(&thread[i], NULL, Batiment::launcher, (void *)&batiments[i]))) {
            fprintf(stderr, "error: pthread_create, rc: %d\n", rc); return EXIT_FAILURE;
        }
    }

Batiment.cpp: launcher 函数,我用它来传递一个对象给线程:

void *Batiment::launcher(void *context)
{
     return static_cast<Batiment*>(context)->jouer();
}

Batiment.h:这里的成员是class

Carte *carteInside;
static void *launcher(void *context);
int id;
void *jouer();

Case.h: 这里是 class 的成员,链接到一个 Batiment 对象:

    Batiment *batiment;

我的Batiment::jouer()方法只是在地图中移动当前对象并射击另一个对象的方法...当我"cout"调用[=26=的对象的当前ID时],所描述的问题发生的地方

Carte.cpp:

for(int i = 0; i<this->x; i++){
    for(int j = 0; j<this->y; j++){
        if(this->carte[i][j].libre == false){
            printf("%d", this->carte[i][j].batiment->id);
        }
    }
}

carte.h: class

成员
std::vector< std::vector<Case> > carte;

编辑:Batiment的构造函数:

Batiment::Batiment(Carte *carte, int i) {
    this->carteInside = carte;
    do{
        this->x = doRand(0, carte->x);
        this->y = doRand(0, carte->y);
    }
    while(!carteInside->carte[x][y].libre);
    this->id = i;
    this->orientation = doRand(0, 3);
    this->longueur = doRand(2, 4);  
    this->vie = 2*(this->longueur)*(this->longueur);    
    carte->carte[this->x][this->y].libre = false;
    carte->carte[this->x][this->y].batiment = this;
}

问题是您通过 Batiment 的构造函数填充 Carte,但使用了一个被破坏的临时对象,使指针无效:

为什么?

在此语句中,您创建了一个临时 Batiment:

   Batiment temp(&carte, i);

您的构造函数显然会在 Carte::carte[][] 中插入指向新创建对象的指针。

不幸的是,您在 for 循环的块中定义了这个临时值:

for(int i = 0; i < nbrBatiments; i++){ //Ajout des Batiments sur le vecteur
        Batiment temp(&carte, i);   // <=== L'instance n'existe que le temps d'une itération !! 
        ...
    }

所以在这个循环的每一次迭代中都会创建和销毁这个临时文件。所以你的指针一离开循环就失效了。

当您稍后引用它时,它是未定义的行为。它能找到任何有意义的值只是一种运气。

顺便说一下,当你在 vector 中推回 temp 时,将创建对象的副本(相同的值,但仍然是另一个地址)。

如何解决?

嗯,保持你最初设计的想法,有几个解决方案。

最简单的方法是在免费商店中创建您的 Batiment:

 Batiment *temp = new Batiment (&carte, i);  

唯一的一点就是某天某个地方需要删除该对象。所以要么你在 Carte 的析构函数中处理这个,要么你改变你的 vecotr 以保留一个指针,以便你以后可以删除所有这些对象。

更好的方法是使用 shared_ptr,它会自行处理内存管理。