Junk Checking

closed account (S6k9GNh0)
When you declare a variable, there's usually junk already in place there. I have a management problem because of this. I have a static image that I want to create on construction on an object but not every time, only if it hasn't been initialized. So, I'm doing something like, if (!myImage) myImage = new my::Image();. If I remember right though, this won't work since the myImage pointer might actually be something other than NULL and I can't initialize it outside of my class to NULL.

1
2
3
4
5
6
7
8
9
10
11
	class cqClass
	{
	private:
		static sf::Image * myImg;
	
	public:
		cqClass() { if (!myImg) myImg = new my::Image(100, 25, my::Color(0, 255, 0)); }
		
			
		static my::Image * GetImage() { return myImg; }
	};
Last edited on
That is only the declaration of myImg; I assume you are defining it somewhere as well. At that point, define the variable to be initialized with value of '0'.

E.g., in cqClass.cpp:

 
sf::Image * cqClass::myImg = 0;


This will guarantee the value is NULL until an instance of cqClass is instantiated. As an FYI - the above definitely won't work in a multi-threaded environment. Something to be aware of, even if it doesn't matter to you right now :)

--Rollie
You're saying your compiler is letting you get away with not defining cqClass::myImg outside the class? You're supposed to always define static member variables.
1
2
3
4
5
struct A{
    static int a;
};

int A::a=0; //this definition *must* exist somewhere 
@helios,
Can't you do this? It works for me:
1
2
3
4
	...
	public:
		const static size_t default_clocks = 4000;
	...
Static constant integers are allowed to be defined inside the class.
closed account (S6k9GNh0)
Why won't this work in a multithreaded environment?

Also, defining outside works I suppose. I actually knew I could do that... just was thinking... something... wrong...

Anyways, I'm doing this so I don't have to keep allocating and deallocating memory for an image. I do plan on using this in a threaded environment though. Why won't this work?
Last edited on
Wait, so myImg is going to service multiple threads? What if one of them changes it? Then it ruins everything for everyone else.
I do plan on using this in a threaded environment though. Why won't this work?
What happens if two threads create the first two instances of cqClass in short succession?
1. Thread 0 checks value of cqClass::myImg.
2. Thread 1 checks value of cqClass::myImg.
3. Thread 0 initializes cqClass::myImg.
4. Thread 1 initializes cqClass::myImg. Memory leak.

It would probably be best to initialize cqClass::myImg in main() and never touch it again. The way it'll be used may or may not be thread-safe. It all depends on exactly what you plan to do with it.
Last edited on
I am not a fan of initializing the image in main, as (given enough such initializations or large enough images), it can affect performance at startup. And if you wind up not using the image at all, maybe it's better to not create it in memory.

Helios is correct - that is a critical section, which needs to be surrounded in mutexes. Also, I notice that GetImage is static. This means it can be called before an instance of cqClass is ever instantiated (and the image itself would never have been allocated).

If the only way to access the image is via the static GetImage method, perhaps the initialization should be in that method instead of the constructor for cqClass. Also, it should likely return a const my::Image, such that one thread can't alter the image while another is reading it.

--Rollie
closed account (S6k9GNh0)
I figured. I'll just make a singleton class that initializes and makes sure everything checks out before I move onto running the program itself. Looks like threads are fun.
Topic archived. No new replies allowed.