• Advertisement
Sign in to follow this  

Dereferencing Problem

This topic is 4250 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

Hey everyone, once again another question. I have a Sprite Class, that holds a pointer to a GLuint called TextureHandle. My Tile Class creates an instance of Sprite, and has a function called CopyTextureTile(GLuint texture).
void Tile::CopyTextureTile(GLuint texture)
{
    TileSprite.TextureHandle = new GLuint;
    TileSprite.TextureHandle = &texture;
}
There is what that function looks like. My texture manager has a function returning GLuint to get a private texture manager texture. That looks like this.
GLuint TextureManager::GetTexture(char TextureID)
{
    if(TextureID == '0')
        return TerrainTextures[0];
    else if(TextureID == '1')
        return TerrainTextures[1];
    else if(TextureID == '2')
        return TerrainTextures[2];
    else if(TextureID == '3')
        return TerrainTextures[3];
    else if(TextureID == '4')
        return TerrainTextures[4];
    else if(TextureID == '5')
        return TerrainTextures[5];
    else if(TextureID == '6')
        return TerrainTextures[6];
    else if(TextureID == '7')
        return TerrainTextures[7];
    else if(TextureID == '8')
        return TerrainTextures[8];
    else if(TextureID == '9')
        return TerrainTextures[9];
    else
        MessageBox(NULL, "That's not a valid texture", "RPG", MB_ICONEXCLAMATION);

    return NULL;
}

My Map class has a 100 x 100 array of "Tile." The constructor calls loadMap to load up the map from a file. It then takes the info from the file, and copies the textures into the Tile.Sprite.TextureHandle, via CopyTextureTile. That Constructor looks like this.
Map::Map()
{
    if(!LoadMap())
        MessageBox(NULL, "The map was not loaded", "RPG", MB_ICONEXCLAMATION);
    for(int yIndex = 0; yIndex < 100; yIndex++)
    {
        for(int xIndex = 0; xIndex < 100; xIndex++)
        {
            MapArray[yIndex][xIndex].ID = MapFileLines[yIndex][xIndex];
            MapArray[yIndex][xIndex].CopyTextureTile(TexMan.GetTexture(MapArray[yIndex][xIndex].ID));
        }
    }
}

MapFileLines[yIndex][xIndex] is a character that was previously read from a file. Later, when I want to render the tiles though, the TextureHandle gives me problems.In my Render Class, I have two functions, RenderTile, and RenderMap.
void Renderer::RenderTile(float x, float y, GLuint Texture)
{
    static int count=0;
    float outx, outy, outx2, outy2;
    outx = (100.0 / (x * 16.0)) - 1.5;
    outx2 = (100.0 / (x * 16.0)) - 1.4375;
    outy = (100.0 / (y * 16.0)) - 1.5;
    outy2 = (100.0 / (y * 16.0)) - 1.4375;
    glBegin(GL_QUADS);
        glBindTexture(GL_TEXTURE_2D, Texture);
        glTexCoord2f(0.0, 0.0); glVertex2f(outx, outy);
        glTexCoord2f(0.0, 1.0); glVertex2f(outx, outy2);
        glTexCoord2f(1.0, 1.0); glVertex2f(outx2, outy2);
        glTexCoord2f(1.0, 0.0); glVertex2f(outx2, outy);
    glEnd();
    count++;
}
void Renderer::RenderMap()
{
    for(int y = 0; y <= 100; ++y)
    {
        for(int x = 0; x <= 100; ++x)
        {
            RenderTile((float)x, (float)y, *TestMap.MapArray[x][y].TileSprite.TextureHandle); //This line
        }
    }
}

When I dereference the pointer to pass it as a GLuint, it has some sort of memory leak, and Windows comes up with a serious error. Could someone point out what I am doing wrong with my pointer? Sorry if I rambled and made things hard to understand. Thanks!

Share this post


Link to post
Share on other sites
Advertisement
Three things:

1) If you assigning your texturehandle, then there is no reason to allocate it before hand. This is a memory leak.
void Tile::CopyTextureTile(GLuint texture)
{
TileSprite.TextureHandle = new GLuint;
TileSprite.TextureHandle = &texture;
}

2) What is the error message, exactly? It would probably be easier for us to help you if you post the entire error message.

3) Read Introduction to Debugging. It uses Visual Studio, but the concepts are applicable to other debuggers.

Share this post


Link to post
Share on other sites
I took that line out, and it still comes up with serious error. I don't get an actual compiler error, It's just one of those windows popups. "RPG.exe has encountered a problem and needs to close. We are sorry for the inconvenience." And I can Send Error Report, or Don't Send. Hehe.

Share this post


Link to post
Share on other sites
Quote:
Original post by Niddles
I took that line out, and it still comes up with serious error. I don't get an actual compiler error, It's just one of those windows popups. "RPG.exe has encountered a problem and needs to close. We are sorry for the inconvenience." And I can Send Error Report, or Don't Send. Hehe.


Memory leak is not an error, because memory leaks usually go undetected unless your program runs for a long time and runs out of memory. You should run the program in the debugger, it will help you locate the real source of the problem.

Share this post


Link to post
Share on other sites
There should be a details button on the runtime-error message box.
Which IDE are you using?

Share this post


Link to post
Share on other sites
I have tried debugger, but I can't seem to understand it, I try to watch variables, and they don't appear. Meh, when I run the debugger on Dev-Cpp, a Warning pops up that says "An Access Violation(Segmentation Fault) raised in your program." That's about all I can pull out of the debugger.

Share this post


Link to post
Share on other sites
You might be able to hit debug in that window too which might bring you to the exact line (or close too it) of where the issue is.

Share this post


Link to post
Share on other sites
That's what it's initialized as
Tile MapArray[100][100];

At Mike: I used the debugger, and came to the conclusion it was on the dereferencing line. Hm.

Share this post


Link to post
Share on other sites
void Renderer::RenderMap()
{
for(int y = 0; y < 100; ++y)
{
for(int x = 0; x < 100; ++x)
{
RenderTile((float)x, (float)y, *TestMap.MapArray[x][y].TileSprite.TextureHandle); //This line
}
}
}

Note that indices go from 0-99 in an array of size 100.
I assume that you are setting TextureHandle to something meaningful as well.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Just to clean up your texture lookup a little bit (sorry I can't help with your problem):

GLuint TextureManager::GetTexture(char TextureID)
{
if ('0' > TextureID || '9'

Share this post


Link to post
Share on other sites
this doesn't answer but just a suggestion to your GetTexture function:

GLuint TextureManager::GetTexture(char TextureID)
{
int textureNumID = TextureID - '0';
if (textureNumID >= 0 && textureNumID < 10)
{
return TerrainTextures[textureNumID];
}
else
{
MessageBox(NULL, "That's not a valid texture", "RPG", MB_ICONEXCLAMATION);
return NULL;
}
}

Share this post


Link to post
Share on other sites
Okay, it no longer sends an error at me, but the window does come up and disappear. And the debugger still gives me that error message. I fixed the array though.

[edit]
When the debugger error message comes, this line pops up.

MapArray[yIndex][xIndex].ID = MapFileLines[yIndex][xIndex];

Another thing it does, is if I get the debugger to run without having it do the above, it says the error, when I get to the line where I declare my Renderer.
Heres my WinMain.

#include <windows.h>
#include <gl/gl.h>
#include "Renderer.h"
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int iCmdShow)
{
WNDCLASS wc;
HWND hWnd;
HDC hDC;
HGLRC hRC;
MSG msg;
BOOL bQuit = FALSE;
float theta = 0.0f;

wc.style = CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "GLSample";
RegisterClass (&wc);


hWnd = CreateWindow (
"GLSample", "OpenGL Sample",
WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
0, 0, 256, 256,
NULL, NULL, hInstance, NULL);


EnableOpenGL (hWnd, &hDC, &hRC);

Renderer MainRenderer;

while (!bQuit)
{
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
bQuit = TRUE;
}
else
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
else
{
MainRenderer.RenderMap();
SwapBuffers (hDC);
Sleep (1);
}
}

DisableOpenGL (hWnd, hDC, hRC);


DestroyWindow (hWnd);

return msg.wParam;
}

Share this post


Link to post
Share on other sites
Renderer.h

#ifndef RENDERER_H
#define RENDERER_H
#include "Map.h"
#include <gl/gl.h>
class Renderer
{
private:
void RenderTile(float x, float y, GLuint Texture);
public:
Renderer();
Map TestMap;
void RenderMap();
};

#endif


Renderer.cpp

#include "Renderer.h"
#include <windows.h>
Renderer::Renderer()
{
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
}
void Renderer::RenderTile(float x, float y, GLuint Texture)
{
static int count=0;
float outx, outy, outx2, outy2;
outx = (100.0 / (x * 16.0)) - 1.5;
outx2 = (100.0 / (x * 16.0)) - 1.4375;
outy = (100.0 / (y * 16.0)) - 1.5;
outy2 = (100.0 / (y * 16.0)) - 1.4375;
glBegin(GL_QUADS);
glBindTexture(GL_TEXTURE_2D, Texture);
glTexCoord2f(0.0, 0.0); glVertex2f(outx, outy);
glTexCoord2f(0.0, 1.0); glVertex2f(outx, outy2);
glTexCoord2f(1.0, 1.0); glVertex2f(outx2, outy2);
glTexCoord2f(1.0, 0.0); glVertex2f(outx2, outy);
glEnd();
count++;
}
void Renderer::RenderMap()
{
for(int y = 0; y <= 100; ++y)
{
for(int x = 0; x <= 100; ++x)
{
RenderTile((float)x, (float)y, *TestMap.MapArray[x][y].TileSprite.TextureHandle);
}
}
}

Share this post


Link to post
Share on other sites
Post the code where the MapArray and MapFileLines are getting declared and initialized.

Share this post


Link to post
Share on other sites
Map.h

#ifndef MAP_H
#define MAP_H
#include <string>
#include "Tile.h"
#include "TextureManager.h"
class Map
{
private:
std::string MapFileLines[100];
std::string FileLineBuffer;
TextureManager TexMan;
bool LoadMap();
public:
Tile MapArray[100][100];
Map();
};

#endif


Map.cpp

#include "Map.h"
#include <windows.h>
#include <fstream>
#include <iostream>
bool Map::LoadMap()
{
int line = 0;
std::ifstream MapFile("Map.txt");
if(!MapFile.is_open())
{
return false;
}
while(!MapFile.eof())
{
std::getline(MapFile, FileLineBuffer);
MapFileLines[line] = FileLineBuffer;
line++;
}
MapFile.close();
return true;
}
Map::Map()
{
if(!LoadMap())
MessageBox(NULL, "The map was not loaded", "RPG", MB_ICONEXCLAMATION);
for(int yIndex = 0; yIndex <= 100; yIndex++)
{
for(int xIndex = 0; xIndex <= 100; xIndex++)
{
MapArray[yIndex][xIndex].ID = MapFileLines[yIndex][xIndex];
MapArray[yIndex][xIndex].CopyTextureTile(TexMan.GetTexture(MapArray[yIndex][xIndex].ID));
}
}
}

Share this post


Link to post
Share on other sites
I don't know if you changed it yet but

for (int y = 0; y <= 100; ++y)
{
//.....
}

/* needs to be */

for (int y = 0; y < 100; ++y)
{
//.....
}


for every loop that you have. the reason being is that you are declaring 100 elements and the index starts with 0 not 1. so you go from 0 - 99, which, if you count it correctly, is 100 elements.

edit: also when you are returning functions, especially with the files, you should accompany them with a MessageBox so you know which function failed. easier to debug that way also.

Share this post


Link to post
Share on other sites
This looks kind of dangerous:

std::string MapFileLines[100];

Are you sure that every std::string inside MapFileLines is 100-characters long?

Share this post


Link to post
Share on other sites
Yay, that fixed it all, except now it's displaying garbage rather than what it's supposed to, but thats a step forward. Thanks for pointing out my stupid mistakes.

Share this post


Link to post
Share on other sites
i wouldn't be surprised if that's due to the fact that you represent the textureIDs with both int and chars and keep converting between the two and your file loading.

i'll say it again in case you didn't see in my above post. make you sure where you load a file it says something like:

bool loadFile ()
{
//...

if (!file.isOpen())
{
MessageBox (/* didn't work */);
return false;
}
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement