C++使用构造函数填充的向量的奇怪行为

Juj*_*nol 3 c++ runtime-error vector stdvector

我正在经历一些使用构造函数填充向量值的"奇怪行为".

所以,我有这个块类,只要调用构造函数,就会填充这个名为blockList的静态向量.

static std::vector<Block*> blockList;

Block::Block(float x, float y)
    : RectangleShape(sf::Vector2f(WIDTH, HEIGHT)) {
    blockList.push_back(this);
    setFillColor(sf::Color(221, 221, 221, 255));
    setPosition(x, y);
}
Run Code Online (Sandbox Code Playgroud)

现在,当我在另一个类中填充值时,我称之为"游戏"; 在它的构造函数中如下:

Game::Game(sf::RenderWindow& window) {
    // other code here

    Block firstBlock(10, 10);
    // possible more blocks here
}
Run Code Online (Sandbox Code Playgroud)

然后试图画画,它崩溃了.另外,该块的坐标打印为(x:9.8439e-12,y:9.84394e-12).现在我尝试做的是把它扔进draw方法(我知道它很糟糕,因为它经常被调用但是出于调试目的):

void Game::drawObjects() {
    // draw other shapes here

    Block oneBlock(50.0f, 50.0f);

    std::cout << std::string(10, '-') << std::endl;
    for (Block* block : Block::getBlockList()) {
        std::cout << block->getPosition().x << " - " << block->getPosition().y << std::endl;
        window->draw(*block);
    }
    std::cout << std::string(10, '-') << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

对象的坐标和绘图完美地工作(即使矢量被大量填充).所以我想知道为什么会这样,并且可以解决这个问题.我不喜欢这个想法,但也许我应该有标志来检测它们是否已经被创建然后在draw方法中创建它们?

son*_*yao 7

所以我想知道为什么会这样

Game::Game(),中,Block firstBlock(10, 10);means firstBlock是一个本地对象,当它超出范围时将被销毁Game::Game().然后由blockList.push_back(this);in 保存的指针blockList成为悬空指针,访问它会导致UB.

以及解决这个问题的可能方法.

你真的需要一个指针向量吗?你可以

static std::vector<Block> blockList;
Run Code Online (Sandbox Code Playgroud)

然后使用它像:

Block firstBlock(10, 10);
blockList.push_back(firstBlock);
Run Code Online (Sandbox Code Playgroud)