Sign in to follow this  

Argg!!! Classes!

This topic is 4856 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Why doesn't this code work! Argg!!!!!!
void MapTiles::InitMapTiles(char *FileName,IDirect3DDevice9 *ag_d3d_device) {

aMapTile = new aTile*[MaxX];
	for (int i=0;i==MaxX;i++) {
		aMapTile[i] = new aTile[MaxY];
	}
	//Get tile types of all and	assign coords to all tiles
	for (int y=0;y==MaxY;y=y+1) {
		for (int x=0;x==MaxX;x=x+1) {
			aMapTile[x][y].mapX=x*32;
			aMapTile[x][y].mapY=y*32;
			FileInput.read((char *) &aMapTile[x][y].Type, sizeof(int));
		}
	}
}
Possible reasons I can come up with: Something to do with classes. It compiles ok, but when it gets to: "aMapTile[x][y].mapX=x*32;" it gives me an unhandled error exception. aMapTile is a struct defined inside the MapTiles class.
struct aTile {
	float mapX,mapY;
	float screenX,screenY;
	int Type;
};
class MapTiles
{
public:
	
	void InitMapTiles(char FileName[256],IDirect3DDevice9 *g_d3d_device);
	aTile **aMapTile;
	IDirect3DTexture9 **aMapTileTexture;
	int MaxX,MaxY;
}
Anyone got any ideas?

Share this post


Link to post
Share on other sites
Quote:
for (int i=0;i==MaxX;i++) {

aMapTile[i] = new aTile[MaxY];

}


The problem may lie in this for loop. Memory is never being allocated. i never equals MaxX. You probably wanted something like "i < MaxX"

Share this post


Link to post
Share on other sites
Why does i never equal maxX?

Doesn't that for loop mean:

Start with i=0. End when i equals MaxX. i = i +1 every turn.

Isn't that what it means? I am probably getting something confused with VB again =/

Share this post


Link to post
Share on other sites
Quote:

Doesn't that for loop mean:

Start with i=0. End when i equals MaxX. i = i +1 every turn.


NO! the second part of the for loop means run _until_ this contion fails. your check fails before it even runs once.

1st iteration -> i = 0; i is not == MaxX, so the contional fails and the loop ends.

Quote:
Original post by MikeMJH
The problem may lie in this for loop. Memory is never being allocated. i never equals MaxX. You probably wanted something like "i < MaxX"


yep, both your for loops should be like:


for (int i=0;i < MaxX;i++) {
aMapTile[i] = new aTile[MaxY];
}

//snip...

for (int y=0;y < MaxY;y=y+1) {
for (int x=0;x < MaxX;x=x+1) {
aMapTile[x][y].mapX=x*32;
aMapTile[x][y].mapY=y*32;
FileInput.read((char *) &aMapTile[x][y].Type, sizeof(int));
}
}




-me

Share this post


Link to post
Share on other sites
Ahh, there we go! I just changed == to != and it works now. Thanks, I keep on getting the simple stupid stuff mixed up. Now it works... somewhat, but I hopefully won't be making that stupid mistake before! So used to using do loops in VB, I am still treating for loops the same. Thanks all for your help!

Share this post


Link to post
Share on other sites
Using a != in a for loop is BAD. Always use <, <=, > or >=. All the others are bad practice.

For instance, consider this code snippet

for (int nTeller = 0; nTeller != 99; ++nTeller)
{
nTeller += 1;
}


It will never reach the != 99 condition, and thus loops forever. However, if you use nTeller < 100, it would have stopped once it went beyong the 99.

Toolmaker

Share this post


Link to post
Share on other sites
operator != isn't always bad in for loops. Don't steer him wrong. When using iterators, it is the best way to know when you've reached the end.


for (vector<int>::iterator pos = v.begin(); pos != v.end(); ++pos)
;



And speaking of BAD programming practices, never use i++ to increment! It is stupid. Always use ++i instead.

The difference is that ++i increments i and returns the result, whereas i++ creates a copy of i, increments the original, and returns the copy (the old value). This is unnecessary in this context and is much slower. Never use i++ unless you for some reason need the original value returned.

Share this post


Link to post
Share on other sites
im sure toolmaker just didnt want to show him that its usefull when using iterators, seeing as hes having problems with just for loops...


anyway, my question is, is it true that doing i++ is actually slower? i mean, isnt this a micro-optimization? i use i++ for every for loop in the 50 + files of my game...

Share this post


Link to post
Share on other sites
Quote:
Original post by graveyard filla
anyway, my question is, is it true that doing i++ is actually slower? i mean, isnt this a micro-optimization? i use i++ for every for loop in the 50 + files of my game...

i++ is indeed slower, and it is indeed a micro-optimization, but since there's no loss of expressivity involved and it's a trivial thing to remember, it's good to get in the habit of using ++i.

Share this post


Link to post
Share on other sites
Quote:
Original post by graveyard filla
anyway, my question is, is it true that doing i++ is actually slower? i mean, isnt this a micro-optimization? i use i++ for every for loop in the 50 + files of my game...


Think what does pre/post increment actually do? pre-increment is pretty obvious it moves up one and returns the value but post increment isn't so much. Post increment returns a copy of the value then increments the original so imagine how this would be implemenated for a iterator type for a list:


....
//pre-increment
iterator& operator++() {
node = node->next;
return *this;
}

//post-increment
iterator operator++(int) {
iterator tmp = *this;
node = node->next;
return tmp;
}



but for built-in types shouldn't be any real concern.

Share this post


Link to post
Share on other sites
Hmm, did not know these things. Thanks for the help guys, and I guess this just shows that VB is a bit too dumb downed..

Now that you guys brought these things up, I got some questions for ya's! First off, if i++ is slower then ++i, is i=i+1 slower then ++i?

Also, I don't see why != is bad.

Quote:

NO! the second part of the for loop means run _until_ this contion fails. your check fails before it even runs once.


Well, if that is correct, would i!=max mean that once i=max, i!=max would return false, and while i was not equal to max, i!=max would return true?

Thanks guys for your help :)

Share this post


Link to post
Share on other sites
When you have to work at a lower level, i.e. with integer loop counters, using < (or <= or > or >=) is good defensive coding practice, to guard against the possibility that you "skip over" the loop condition. There might be a valid reason why you want to modify the counter variable within the loop, for example. Consider:

void handleUpToNThings(Thing[] things, int n) {
for (int i = 0; i < n; ++i) {
things[i].handle();
if weird_condition(thing) i += 5;
}
}


There's no guarantee here that i will ever be equal to n, and there isn't even a good way of fixing that fact, so we use '<'. Otherwise we could get an infinite loop (and in this case, run out of things and crash with a segfault).

Iterators aren't necessarily logically ordered (just comparable for equality), so you're kinda stuck with '==' and '!='. However, they're also safer, and designed to handle that situation. (i.e., they'll have overloads for operator + and so on that prevent serious problems.)

RE i++ vs ++i: "i++" is idiomatic C for a loop counter, from back when it didn't really matter (because there were no classes around) and I guess people figured it looked better. On any half-decent compiler these days (i.e. not written at 2am by a group of drunken university students), they should compile to basically the same code for primitive types (assuming you're not actually using the 'return value' of the increment). However, for any classes or structs, this optimization is impossible, because the language can't even guarantee that the two overloaded operators have anything to do with each other. (Of course, it can't guarantee that a function called add() does anything having to do with addition, either; but IMHO I still think the design of C++'s operator overload scheme could use some work. Even though I do miss having overloads in Java.)

'i = i + 1' will again optimize to the same thing for primitive types. But note that i++ and ++i are not mere statements, but expressions:


j = i++; // Effectively: j = i; i = i + 1;
j = ++i; // Effectively: i = i + 1; j = i;

Share this post


Link to post
Share on other sites
Quote:
Original post by bobthebobert
Now that you guys brought these things up, I got some questions for ya's! First off, if i++ is slower then ++i, is i=i+1 slower then ++i?

No, it is exactly identical. Maybe a long time ago, a bad compiler would generate slower code (which is the main reason we have increment/decrement operators), but now they're the same. "return i=i+1" will return the new value of i; it is identical in both speed and operation to "return ++i".

Quote:
Also, I don't see why != is bad.

A simple example is when dealing with floating-point numbers (decimals). Say you have this:

for( float F = 0; F != 1; F += 0.1 )
{ /* ... */ }

0.1 isn't stored precisely in floating-point format; as a result, F will never ever equal 1. The closest it comes will be something like 1.000034 maybe. You need to say "< 1" instead.

Share this post


Link to post
Share on other sites
Quote:
Original post by bobthebobert
Also, I don't see why != is bad.


It is bad because of the situation, not because it's bad as a codingstyle.

This is the != situation: (start: 0; you-want-to-loop: 6;)

1 2 3 4 5 6 | 7 8 9 10 11 12


This is the < situation: (start: 0; you-want-to-loop: 6;)

1 2 3 4 5 6 | x x x x~ x~ x~


As you can see, the < situation reaches the breaking-statement (displayed as |) and quits (displayed as x). If for some reason the loop SKIPS the breaking-statement, it will not run in this case, because anything beyond the statement is x.
BUT if you look at the != situation, anything beyond the breaking-statement is still valid.
So if anything would've caused the loop to jump after the statement, you'd get a) an endless loop, or b) an access violation.

Back to your first situation, you had ==, and as you should know in C++ when you declare an array like this: char Arr[6]; The sixth element is 5 (because the first is 0) so if you access 6 (which is actually the seventh element) you're [b]accessing other memory, aka you caused a memory access violation.

Share this post


Link to post
Share on other sites
I see what you guys are saying about the != thing, but for what I am using it for now is ok I think. In all of my for loops where I use !=, not once do I change the variable in the code which in some way might make the code continue infinetly. (AKA, if I use ++i, in my loop code I never change the variable i). However I do see what you guys are saying, and appreciate your help.

Share this post


Link to post
Share on other sites
I think for ints you will generally be okay, but keep in mind that even if you don't do anything that will obviously cause your variable to "skip," it can still happen with floating point numbers, simply becuase some decimals cannot possibly be represented with a finite number of binary bits.

To illustrate this problem in binary, consider the same problem in decimals. If you wanted to add 1/3 to i each iteration until i was equal to 1, the loop would never break! 1/3 is going to round at some point, say at 0.3333. Thus,

3 * 0.3333 == 0.9999 != 1

Binary arithmatic is even less forgiving, and you must expect rounding to occur anytime floating point numbers enter an equation.

So, again, ints might be safe, but get out of the habit of using != becuase it won't be obvious later when you use floats and something doesn't work.

Share this post


Link to post
Share on other sites

This topic is 4856 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this