微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

指针的意外行为操作时但使用双指针时定义的行为

如何解决指针的意外行为操作时但使用双指针时定义的行为

我对指向变量的指针行为背后的推理感到非常困惑。我会想,如果我附加一个指向 vector 的指针并访问它,无论我改变了指针本身,它仍然应该在同一个变量上工作。我的意思是,例如,我有一个整数指针向量,我修改一个在其他地方定义的变量,该变量已附加到该向量。如果我要打印它们,它应该更新向量(实际上不是),但它应该打印一个整数的新值。我正在尝试将其应用于 SDL2 中的 SDL_Texture*,但这并不完全合理。总之,同样的概念在那里应用,但我使用的是纹理。我修改了纹理并用它做“事情”,但是在我渲染它的循环结束时,向量仍然迭代到附加到它的 SDL_Texture* 无论如何。我的问题是,当我改变和修改纹理时,当我去渲染它时它没有出现。这不是因为纹理没有正确加载或任何东西(我已经测试过它,而不是使用矢量,我绘制它原始)但是当使用矢量时它不能正常工作。代码如下:

void Main::Mainloop()
{

    Screen_Object m_Screen_Object;

    TTF_Font* font = TTF_OpenFont("Anonymous_Pro.ttf",30);
    SDL_Surface* surf = TTF_RenderText_Blended(font,"Starting fps",{0,0});
    SDL_Texture* tex = SDL_CreateTextureFromSurface(Render::Get_Renderer(),surf);
    SDL_FreeSurface(surf);
    SDL_Rect rct = {20,100,0};
    SDL_QueryTexture(tex,NULL,&rct.w,&rct.h);
    m_Screen_Object.Add_Texture(tex);


    Uint32 start,finish,counter;
    counter = 0;
    start = SDL_GetTicks();
    finish = SDL_GetTicks();



    bool running = true;

    while (running)
    {
        Events::Event_Loop();
        if (Events::Quit_Application()){
            running = false;
            break;
        }


        ///Clear display to color
        SDL_SetRenderDrawColor(Render::Get_Renderer(),255,255);
        SDL_RenderClear(Render::Get_Renderer());



        ///Do stuff here
        m_Screen_Object.Draw_Textures();
        

        finish = SDL_GetTicks();
        counter += 2;
        if (finish - start >= 500)
        {
            start = SDL_GetTicks();

            SDL_DestroyTexture(tex);
            std::string fps = std::to_string(counter);
            surf = TTF_RenderText_Blended(font,fps.c_str(),0});
            tex = SDL_CreateTextureFromSurface(Render::Get_Renderer(),surf);
            SDL_FreeSurface(surf);
            SDL_QueryTexture(tex,&rct.h);
            counter = 0;
        }


        SDL_RenderPresent(Render::Get_Renderer());

    }


    SDL_DestroyTexture(tex);
    TTF_CloseFont(font);

}




int main(int argc,char* argv[])
{

    Main::Mainloop();

    return 0;
}

这里是 Screen_Object 的声明: 标题中:

std::vector < SDL_Texture* > m_Textures;

在 .cpp 中:

void Screen_Object::Add_Texture(SDL_Texture* p_Texture)
{
    m_Textures.push_back(p_Texture);
}


void Screen_Object::Draw_Textures()
{

    for (unsigned int i=0; i < m_Textures.size(); i++)
    {
        SDL_Rendercopy(Render::Get_Renderer(),m_Textures[i],&m_Rect);
    }

}

在这代码没有按照我认为应该的方式工作,因为我不明白为什么它不工作,但是当我将向量的类型更改为 SDL_Texture** 时,代码工作正常。没有 **代码到底有什么问题,我无法从逻辑上理解为什么它不能正常工作

解决方法

问题似乎是您将指针存储在向量中,但在向量之外使指针无效。

void Screen_Object::Add_Texture(SDL_Texture* p_Texture)
{
    m_Textures.push_back(p_Texture);
}

void Main::Mainloop()
{
    Screen_Object m_Screen_Object;
    //...
    SDL_Texture* tex = SDL_CreateTextureFromSurface(Render::Get_Renderer(),surf);
    //...
    m_Screen_Object.Add_Texture(tex); // <-- add pointer to vector
    //...
    tex =  SDL_CreateTextureFromSurface(Render::Get_Renderer(),surf); // <-- This changes the pointer,but has no effect on the vector's 
    //...

所以在该行之后的任何内容,如果您访问 m_Textures 向量中的指针,向量中的指针不再有效,或者更糟的是,它有效,但指向旧的(但仍然有效){ {1}}。

一个非常简单的解决方案是通过获取对该指针的引用来确保您使用存储在 SDL_Texture 中的指针:

m_Textures

然后在此之后使用 void Main::Mainloop() { Screen_Object m_Screen_Object; TTF_Font* font = TTF_OpenFont("Anonymous_Pro.ttf",30); SDL_Surface* surf = TTF_RenderText_Blended(font,"Starting fps",{0,0}); SDL_Texture* tex = SDL_CreateTextureFromSurface(Render::Get_Renderer(),surf); m_Screen_Object.Add_Texture(tex); // <-- Immediately do this auto& texRef = m_Screen_Object.back(); // <-- Get a reference to the pointer. 。这是对添加到向量的指针的实际引用,而不是指针的副本。

那么循环将很简单:

texRef

这会改变存储在向量中的实际指针。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。