Vector iterator not derefranceable

Started by
3 comments, last by Crusable77 10 years, 10 months ago

Hello, I am working on an animation class that has one std::vectors of textures for both a left and right direction of textures. The point of this class it to hold the different frames and then after a specific amount of time has passed, update the frame and then return a texture for rendering. When I compile the code I get this window(attacked file). Here is the animation class:

Animation.hpp



#ifndef ANIMATION_HPP
#define ANIMATION_HPP

#include <SFML/Graphics.hpp>
#include <vector>

enum DIRECTION{LEFT = 1, RIGHT = 0};

class Animation{

public:
	Animation();
	~Animation();
	void setAnimation(sf::Image sheet, sf::Vector2f frameSize);
	void setDirection(DIRECTION dir);
	void update(sf::Time deltaT);

	sf::Texture& getCurrentFrame(){return *m_Iter;}

private:
	sf::Image m_sfSpriteSheet;
	sf::Vector2f m_sfFrameSize;
	std::vector<sf::Texture> m_LeftFrames;
	std::vector<sf::Texture> m_RightFrames;
	std::vector<sf::Texture>::iterator m_Iter;
	int m_iXFrames , m_iYFrames, m_iCurrentFrame;
	DIRECTION m_CurrentDirection;
	sf::Time m_sfFrameTime;
};

#endif //ANIMATION_HPP

Animation.cpp



#include "Animation.hpp"

Animation::Animation() : m_CurrentDirection(LEFT), m_sfFrameTime(sf::seconds(0)){}

Animation::~Animation(){}

void Animation::setAnimation(sf::Image sheet, sf::Vector2f frameSize){

	m_sfSpriteSheet = sheet;
	m_sfFrameSize = frameSize;

	//get the size of the sheet so I can set the vector of texures
	m_iYFrames = (int)(m_sfSpriteSheet.getSize().y / m_sfFrameSize.y);
	m_iXFrames = (int)(m_sfSpriteSheet.getSize().x / m_sfFrameSize.x);

	sf::Texture tempTex;

	//split up sheet
	for(int y = 0; y < m_iYFrames; ++y){

		for(int x = 0; x < m_iXFrames; ++x){

			tempTex.loadFromImage(m_sfSpriteSheet, sf::IntRect((int)(x * m_sfFrameSize.x), (int)(y * m_sfFrameSize.y), 
				                  (int)(m_sfFrameSize.x), (int)(m_sfFrameSize.y)));

			if(y == 0) m_LeftFrames.push_back(tempTex);
			if(y == 1) m_RightFrames.push_back(tempTex);
		}
	}

	*m_Iter = m_LeftFrames[0];
}

void Animation::setDirection(DIRECTION dir){

	m_CurrentDirection = dir;
	m_iCurrentFrame = 0;

	if(m_CurrentDirection == LEFT) *m_Iter = m_LeftFrames[m_iCurrentFrame];
	if(m_CurrentDirection == RIGHT) *m_Iter = m_RightFrames[m_iCurrentFrame];

}

void Animation::update(sf::Time deltaT){

	m_sfFrameTime += deltaT;

	//If one second as passed then change frame
	if(m_sfFrameTime >= sf::seconds(1)){

		m_sfFrameTime = sf::seconds(0);
		++m_iCurrentFrame;
		if(m_iCurrentFrame == m_iXFrames) m_iCurrentFrame = 0;

		if(m_CurrentDirection == LEFT) *m_Iter = m_LeftFrames[m_iCurrentFrame];
		if(m_CurrentDirection == RIGHT) *m_Iter = m_RightFrames[m_iCurrentFrame];
	}
}

[attachment=16101:error.PNG]

Advertisement
I don't see anywhere in your code where you initialize m_Iter.

Do you even need an iterator? The current frame index will probably suffice.

You have an iterator. The iterator never is assigned anything (as SiCrane noticed). However, the iterator is dereferenced so what it is (not) pointing at can be assigned to.


int *myInt = NULL; //Doesn't point to anything.
*myInt = 5; //Crash!

For example, you have:


*m_Iter = m_LeftFrames[0];

This says, "take what m_Iter" is already pointing to, and assign the value of m_LeftFrames[0] to it". It's not saying, "make it point to m_LeftFrames[0]", which I think is what you are wanting. Since m_Iter isn't yet pointing to anything, it's similar (in concept) to dereferencing a null pointer.

A normal pointer will work just as fine, but if you want a iterator, you have to do it like this:


m_Iter = m_LeftFrames.begin(); //Gets an iterator to the first element.
m_Iter = (m_LeftFrames.begin() + index); //Gets an iterator to the nth element.

Note that we assigned to the iterator without dereferencing it. Dereferencing gets the object it is pointing to.

Warning: Your iterators will become invalid if the container is resized or elements inserted or erased.

Thanks

This topic is closed to new replies.

Advertisement