Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sf::Text in vector  (Read 1140 times)

0 Members and 1 Guest are viewing this topic.

Askhalog

  • Newbie
  • *
  • Posts: 2
    • View Profile
sf::Text in vector
« on: April 01, 2020, 10:44:40 pm »
Hi,
I insert multiple sf::Text in vector in other function. When I try to loop my vector in the main and insert the sf::Text value into windows->draw my program crash and display segmentation fault (core dumped).

#include "../includes/sfml.h"
#include <iostream>
#include <vector>

std::vector<sf::Text>   ft_load_text(sf::Font font)
{
        std::vector<sf::Text>   v_text;
        sf::Text                                text;
        sf::Text                                text2;
        sf::Text                                text3;

        text.setFont(font);
        text.setString("test");
        text.setCharacterSize(20);
       
        text2.setFont(font);
        text2.setString("test1");
        text2.setCharacterSize(20);
       
        text3.setFont(font);
        text3.setString("test2");
        text3.setCharacterSize(20);

        v_text.push_back(text);
        v_text.push_back(text2);
        v_text.push_back(text3);
        return (v_text);
}

int main()
{
        SFMLClass*      c_sfml = new SFMLClass();
        sf::RenderWindow*       window = c_sfml->getWindow();
        std::vector<sf::Sprite> v_sprite;

        sf::Sprite      *sprite = ft_load_gb();
        v_sprite.push_back(*sprite);

        sf::Font font;
        if (!font.loadFromFile("arial.ttf"))
                return EXIT_FAILURE;

        std::vector<sf::Text>   v_text = ft_load_text(font);
       
        // it works
        for (sf::Text tt: v_text)
        {
                std::string     test_text(tt.getString());
                std::cout << test_text << std::endl;
        }

        while (window->isOpen())
        {
                sf::Event event;
                while (window->pollEvent(event))
                        if (event.type == sf::Event::Closed)
                                window->close();
                // clear the buffers
                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                for (sf::Sprite i : v_sprite)
                        window->draw(i);

                // it doesn't work
                for (sf::Text tmp: v_text)
                        window->draw(tmp);
                window->display();
        }
        return EXIT_SUCCESS;
}
 

Can you help me fix that?

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: sf::Text in vector
« Reply #1 on: April 02, 2020, 07:28:45 pm »
Each text holds - internally - a pointer to the font it is to use when drawn. You set this pointer when using setFont().
You are passing the font by value to the ft_load_text function so the font inside that function is a temporary copy. All of the texts then point to that copy and then the copy is destroyed when the function ends.
Any further use of those texts will attempt to use the pointer to memory that is not longer allocated.

The solution is to pass fonts by reference (or pointer), like this:
std::vector<sf::Text>   ft_load_text(const sf::Font& font)
(notice the ampersand)
Also, since your function isn't modifying the sf::Font, it can be a const reference. I added const to the code line above already ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Askhalog

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: sf::Text in vector
« Reply #2 on: April 03, 2020, 09:40:42 am »
It works! I often forget to put a const ... I will try to remember it.
Thanks for your help