Умножаемый объект изменяется после изменения одного указателя - PullRequest
0 голосов
/ 10 октября 2018

Я просто выполняю задание Uni, которое, правда, очень простое.Но я застрял.Задача проста, просто использовать SDL2 для создания системы отображения входных данных.Я создаю структуру Button, которая имеет имя, прямоугольник и назначенный ключ кнопки.

vector<Button>buttons = {
     Button("up", SDL_Rect{ 100,100,100,20 },"Up"),
     Button("down", SDL_Rect{ 100,200,100,20 },"Down"),
     Button("left", SDL_Rect{ 100,300,100,20 },"Left"),
     Button("right", SDL_Rect{ 100,400,100,20 },"Right"),
     Button("reset", SDL_Rect{ 400,400,100,20 },"R")
};

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

if (evt.type == SDL_MOUSEBUTTONDOWN)
{   
    int x, y;
    SDL_GetMouseState(&x, &y);
    for (auto &b : buttons)
    {
        if (x > b.btn_rect.x && x<(b.btn_rect.x + b.btn_rect.w) && y > b.btn_rect.y && y < (b.btn_rect.y + b.btn_rect.h))
        {
            cout << "Button " << b.btn_name << " clicked" << endl;
            btClicked = &b;
            break;
        }
    }
}

Теперь вот странная вещь произошла.Когда btClicked не равен NULL, я назначаю имя клавиши этой кнопке.Но каждый раз, когда я назначаю другую кнопку для btClicked, предыдущие кнопки, назначенные для btClicked, также меняют имя ее ключа.

if (evt.type == SDL_KEYDOWN)
{
    if(btClicked!=NULL)
    {
        btClicked->assigned_key = SDL_GetKeyName(evt.key.keysym.sym);//breakpoint here
        btClicked = NULL;
    }

Вы можете увидеть отладку точки останова ниже.Все предыдущие кнопки, которые были назначены btClicked, все изменены.Но btClicked указывает только на одну из кнопок. Точка останова Отладка

Кто-нибудь знает, что здесь происходит?Пожалуйста, помогите.

1 Ответ

0 голосов
/ 10 октября 2018

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

Самый простой способ добиться этого - сделать ваш член Button::assigned_key std::string вместо необработанного const char*.

В любом случае, это почти всегда хорошая идея, поскольку сохранение члена const char* в семантике владения объектом делает его более уязвимым и делает приложение гораздо более подверженным подобным ошибкам и утечкам памяти.

...