Не можете получить то же значение указателя, используя значение указателя на указатель? - PullRequest
0 голосов
/ 08 апреля 2020

Программа cra * sh. Я пытаюсь реализовать функцию Brick ** create_bricks(), которая возвращает указатель на указатель Brick (потому что я хочу создать массив Bricks и вернуть позицию первого). Я дергаю себя за волосы, и последнее, что я делаю после нескольких неудачных попыток, ошибок и исследований, - это упрощаю мой код и проверяю значение указателей строка за строкой. Когда я разыменовываю the_brick как *the_brick в игре с функцией рисования l oop, оно не получает того же значения, которое присвоено new Brick() для ptr_brick внутри create_bricks() функции. Я использую SFML, но проблема связана с указателями.

Примечание : если я возвращаю Brick * из create_bricks с правильными модификациями, он работает нормально (и рисует кирпич) , но мне нужно создать несколько кирпичей, а не только один.

#include "Brick.h"

int main()
{
    ...

    while (window.isOpen())
    {
        Brick ** ptr_bricks = create_bricks();
        Brick * ptr_brick = *ptr_bricks;
        window.draw(*the_brick);
    }
    return 0;
}
Brick ** create_bricks()
{
    Brick * ptr_brick = new Brick();
    ptrBrick->setPosition(150, 20);
    return &ptrBrick;
}
#include "Brick.h"

Brick::Brick()
{
    LOG(INFO) << "Brick constructor";

    setPosition(10, 10);
    setSize(sf::Vector2f(100, 20));
    setFillColor(sf::Color::Green);
    setOutlineThickness(1);
}

Brick::~Brick()
{
    LOG(INFO) << "Brick destructor";
    //dtor
}

Спасибо

1 Ответ

5 голосов
/ 08 апреля 2020

Проблема в выражении return в функции create_bricks:

return &ptrBrick;

Здесь вы возвращаете указатель на локальную переменную ptrBrick. Время жизни этой переменной закончится, когда закончится функция, и любой указатель на нее станет недействительным, как только функция завершится.

Естественное решение C ++ для возврата «массива» из функции вместо этого нужно вернуть std::vector:

std::vector<Brick*> create_bricks()
{
    Brick* brick = new Brick;
    brick->setPosition(150, 20);
    return { brick };
}

Если Brick не является полиморфным c классом, вам даже не нужно использовать вектор-указатель, а вектор простого Brick objects (std::vector<Brick>).

Если вы продолжаете использовать указатели, вы должны выделить массив указателей для Brick, что означает new Brick*[number_of_bricks] (или new Brick[number_of_bricks], если полиморфизм не требуется).

...