Home > Enterprise >  C Reference being duplicated when generated in loop at runtime
C Reference being duplicated when generated in loop at runtime

Time:10-09

I have recently switched from C# to C trying to learn SFML for graphical animation.

I am trying to generate multiple CircleShape with random radius at runtime whose reference is saved as an object class, whose reference is then saved in a vector array.

However, after generating the shapes and iterating through the array to draw the shapes from the vector array, it seems that all of them are references to the same shape.

My Code:

#include <SFML/Graphics.hpp>
#include <iostream>
#include <random>
#include <ctime>

template <class T>
class Entity {
    T* m_shape;
    
public:
    Entity(T* shape)
    {
        m_shape = shape;
    }

    T* getShape() {
        return m_shape;
    }
};

class ShapesManager {
    std::vector<Entity<sf::CircleShape*>*>* circleShape;

public:
    ShapesManager()
    {
        circleShape = new std::vector<Entity<sf::CircleShape*>*>();
    }

    std::vector<Entity<sf::CircleShape*>*>* getCircleShapes() 
    {
        return circleShape;
    }

    void addCircleShape(Entity<sf::CircleShape*>* EntityToAdd) {
        circleShape->push_back(EntityToAdd);
    }
};

int main()
{
    const int windowWidth = 800;
    const int windowHeight = 600;

    sf::RenderWindow window(sf::VideoMode(windowWidth, windowHeight), "SFML works!");
    //window.setVerticalSyncEnabled(true);
    window.setFramerateLimit(60);

    ShapesManager m_entityManager;

    int lowSize = 25;
    int highSize = 80;

    for (int i = 0; i < 2; i  ) {
        srand(i   5732   (i * 524));

        float circleRadius = lowSize   static_cast<float>(rand()) * static_cast<float>(highSize - lowSize) / RAND_MAX;

        sf::CircleShape* someValue = new sf::CircleShape(circleRadius);
        (*someValue).setPosition((circleRadius * 2), (circleRadius * 2));
        Entity<sf::CircleShape*>* myObj = new Entity<sf::CircleShape*>(&someValue);
        m_entityManager.addCircleShape(myObj);
    }

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        window.clear();

        for (Entity<sf::CircleShape*>* cE : ((std::vector<Entity<sf::CircleShape*>*>)* m_entityManager.getCircleShapes())) {
            Entity<sf::CircleShape*> myCircleEntity = *cE;
            sf::CircleShape* cS = *myCircleEntity.getShape();
            window.draw((*cS));
        }

        window.display();
    }

    return 0;
}

I have gone through my code multiple times to make sure I am not referencing a single shape for all other shapes.

*I have come across "Shared Pointers/Unique Pointers" while trying to search for a solution, though I have yet to get the grasp of it, but if that is what I should be using to help overcome my issue, make sure to mention it in comments as I am looking more for knowledge than a direct solution.

CodePudding user response:

I think @AlanBirtles is right. On each iteration new sf::CircleShape(circleRadius); allocates new memory, so the pointer someValue will point to the different memory addresses each time. You can't say the same about the memory address of the someValue itself, in your case it seems that the pointer someValue is created in the same memory address on each iteration, that's why taking a reference to this pointer returns the same value on each iteration.

The solutions @AlanBirtles suggested should be enough.

  • Related