Skip to main content
GameDev.net gamedev.net
🔒 Locked

Same code, different results?

Started by Programmer16 May 1, 2004 at 11:39 PM 13 replies 500+ views
Original Post
Programmer16
Programmer16
I''m using code that I''ve used before, but now I''m getting different results. I''m using it exactly how I use to, but it don''t work:
// m_ucTilenumbers is of unsigned char* type. All values are 0

// m_rAreas is of type RECT*.

// m_iColumns = 25

// m_iTileSize = 32

// This is my code, which I''ve used before and which I got out

// of Jim Adams RPG book.

m_rAreas[iSector].left = (m_ucTilenumbers[iSector] % m_iColumns) * m_iTileSize; // Works fine

m_rAreas[iSector].top = (m_ucTilenumbers[iSector] / m_iColumns) * m_iTileSize; // Doesn''t work; produces 192. If I do just 

// (m_ucTilenumbers[iSector] / m_iColumns), the result is 6.

I just don''t understand why its doing this now. Thanks, Donny, Dragonfire Games =========================================================== using DirectX9/C++(MSVC++ 6 Pro. Ed.) ===========================================================
alnite
alnite
Chances are you might have changed something else that affects your code. You have just forgotten it.
Programmer16
Programmer16
Nope, I've check the code and its almost exactly the same (only difference is I'm using a RECT* instead of int's).

Plus, if I use ofstream to do the alg. it gives me 192 too.:
(m_ucTilenumbers[iSector] / m_iColumns) * m_iTileSize
I used ofstream to save m_ucTilenumbers[iSector] to a file and it saves 0, m_iColumns is saved as 8 (which is what it should be, not the 25 that I said above), and m_iTileSize is saved as 32. Which is all correct.

As another note, my other book uses the same code:
((int)(TileNumber / NumberOfColsInTileSet)) * TileSize;

Thanks,
Donny, Dragonfire Games
===========================================================
using DirectX9/C++(MSVC++ 6 Pro. Ed.)
===========================================================

[edited by - Programmer16 on May 1, 2004 12:46:57 AM]

[edited by - Programmer16 on May 1, 2004 12:56:08 AM]
MaulingMonkey
MaulingMonkey
Did you initialize your memory? or did you just alloc()/new[] and assume it was 0ed?

For the second line to evaluate to 192, m_ucTilenumbers[iSector] can not be 0. Otherwise, you have 0/X which is 0 (unless X = 0, in which case it is undefined, and you''d get a division by 0 error) which is then multiplied by anything (0*Y) which is 0 for all Y.

Either you''ve set m_ucTilenumbers[iSector] to something besides 0, you never set it at all, or iSector points to a cell beyond the memory block you allocated/initalized, and is reading from somewhere else in memory.
Krippy2k
Krippy2k
If m_ucTilenumbers[iSector] is == 0, then both of those lines should return 0. If they aren't, chances are good that you have overwritten some memory bounds somewhere, maybe one of your arrays isnt getting initialized right.

What does your declaration for m_rAreas, and m_ucTilenumbers look like, and what is iSector equal to at the time you are getting that result?

You should also really learn to use the debugger, instead of writing the values to a file to see what is going on. It is a very valuable tool

Peace

Oops, too slow.

[edited by - krippy2k on May 2, 2004 1:59:08 AM]
MaulingMonkey
MaulingMonkey
quote:
Original post by Krippy2k
Oops, too slow.



Nah, I''m just too fast. XD
Programmer16
Programmer16
I know that after you allocate memory you still have to set it. This fixes the problem (if I just go through and do m_ucTilenumber = 0), but I need to load it from a file.

As for using the debugger I do use it (my two error functions both use it), but its alot easier using files, since I don't have to convert it from a number to a string.

Now I'm having a second problem:

#include <windows.h>
#include <fstream.h>

unsigned char* pTiles = NULL;

int main()
{
int iCols = 25;
int iRows = 19;
int iSize = 32;
pTiles = new unsigned char[475];
for(int a = 0; a < 475; a++)
{
pTiles[a] = 0;
}

ofstream fout("map.txt", ios::binary);
fout.write((char*)&iCols, sizeof(int));
fout.write((char*)&iRows, sizeof(int));
fout.write((char*)&iSize, sizeof(int));
fout.write((char*)&pTiles, sizeof(unsigned char[475]));
fout.close();

delete [] pTiles;
return 0;
}


When I use this, for some stupid reason its putting the current filename (c:\directories_here\cpp1.exe) in the file.

Thanks,
Donny, Dragonfire Games
===========================================================
using DirectX9/C++(MSVC++ 6 Pro. Ed.)
===========================================================

[edited by - Programmer16 on May 2, 2004 2:14:10 AM]

[edited by - Programmer16 on May 2, 2004 2:17:41 AM]
h3r3tic
h3r3tic
should be:
fout.write((char*)pTiles, sizeof(unsigned char[475]));

without the ''&''
Programmer16
Programmer16
quote:
Original post by h3r3tic
should be:
fout.write((char*)pTiles, sizeof(unsigned char[475]));

without the ''&''



So you only need the ''&'' when you''re using a non char data type? Thanks, everything works now.


Thanks,
Donny, Dragonfire Games
===========================================================
using DirectX9/C++(MSVC++ 6 Pro. Ed.)
===========================================================
Programmer16
Programmer16
I use the fstream when I''m working on something I''m going to release. The second code I''m never going to release (since it was obviously just meant to write that to the file and be done), so I just use the fstream.h. Saves me the trouble of writing using namespace std everytime I create a dumper like that. Thanks for all the help guys

Thanks,
Donny, Dragonfire Games
===========================================================
using DirectX9/C++(MSVC++ 6 Pro. Ed.)
===========================================================
Krippy2k
Krippy2k
quote:
Original post by Programmer16
So you only need the ''&'' when you''re using a non char data type?


pTiles is declared as:
unsigned char* pTiles = NULL;

Therefore pTiles is a pointer to an array of unsigned chars, and not an unsigned char itself. The & operator returns a pointer to the variable being referenced. Since pTiles is already a pointer, &pTiles is a pointer to a pointer, which is not desirable in most cases.

Peace
Krippy2k
Krippy2k
BTW, I mentioned earlier that you should learn to use the debugger. You said you preferred to use fstream because you dont have to convert numbers to a string... I dont think you understand how to use the debugger right.

In MSVC, if you set a breakpoint on a particular line of code, and execute the application, the debugger will break at the line of code you marked. You can then just hold your mouse pointer over any of the variables and it will show you the value. You can hit F10 to step through one line of code at a time, and watch how each variable is being changed as a result of each line. You can also set a ''watch'' on a variable, and it will display the value of that variable in a little window off to the side while you step through the code.

By the time you write out the fstream code to write this stuff to a file, you could have already run the debugger and had the information.

The debugger is one of the most important tools in a programmer''s arsenal.

Peace
Programmer16
Programmer16
Oh, I''ve been awake too long. I thought you were talking about the debug window (where the text is). I know how to use the debugger, but all it said was ''Error''. No matter how I declared it (m_ucTilenumbers = NULL;, etc) it would just say Error.

Thanks,
Donny, Dragonfire Games
===========================================================
using DirectX9/C++(MSVC++ 6 Pro. Ed.)
===========================================================
Krippy2k
Krippy2k
Ahh. Make sure you compile it in the Debug configuration, if you compile it in Release mode it doesn''t keep debugging information and most stuff will either show an error, or an incorrect value.

Peace

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.