|
-
December 30th, 2007, 12:35 AM
#1
Member function parameter corruption ???
I'm getting a strange issue when calling a member function of a class I've defined. I'm trying to do Perlin Noise and writing to screen using SDL in Visual C++ 2005.
The main code is
Code:
#include <cstdio>
#include "gfxcore.h"
#include "sdl/sdl_opengl.h"
#include "Level.h"
#include "terrain.h"
#ifdef _MSC_VER /* Visual C++ pragmas */
#pragma comment (lib, "opengl32")
#pragma comment (lib, "glu32")
#pragma comment (lib, "sdl")
#pragma comment (lib, "sdlmain")
#pragma comment (lib, "zdll")
#endif
int main(int argc, char** argv)
{
CGfxcore* gfxc = new CGfxcore();
if (!(gfxc->initialize(640,480,32)))
{
printf("Error initializing SDL\n");
delete gfxc;
return -1;
}
CTerrain * tr = new CTerrain(384);
tr->generatePerlinNoise ( 4, 0.1 );
The call marked in bold is where I'm getting problems (I pass e.g. 4 as first parameter, but the member function reads garbage like 498512 instead of 4!!!). The member functions as well as constructors/destructors of CTerrain class are:
TERRAIN.H
Code:
#pragma once
#include "sdl/sdl.h"
// class for generating square terrains
class CTerrain
{
public:
CTerrain(void);
CTerrain(int sq_size);
~CTerrain(void);
void generatePerlinNoise (int n_oct, double pp);
unsigned char* getPixelData () { return this->pixeldata; };
private:
unsigned char* pixeldata;
int tsize; // terrain square size
};
terrain.cpp follows...
Code:
#include "Terrain.h"
#include "Utility.h"
#include <cstdio>
CTerrain::CTerrain(void)
{
}
CTerrain::~CTerrain(void)
{
delete[] pixeldata;
}
CTerrain::CTerrain(int sq_size)
{
// terrain size must be power of 2
if (sq_size && !(sq_size & (sq_size - 1)))
printf ("WARN- CTerrain size %d - must be power of 2\n", sq_size);
tsize = sq_size;
pixeldata = new unsigned char[sq_size*sq_size];
}
// perlin noise generation function
// parameters:
// n_oct - octaves
// pp - persistence (defines frequency/amplitude for each octave)
void CTerrain::generatePerlinNoise(int n_oct, double pp)
{
// HERE I'M GETTING GARBAGE VALUES FROM n_oct PARAMETER
// However... pp is ALWAYS correct.
}
What I was thinking is that the SDL.DLL library is corrupting my own program memory, but I think it runs on another memory space. Anyone tried luck with Visual C+SDL?
Thank you very much.
-
December 30th, 2007, 01:31 AM
#2
Re: Member function parameter corruption ???
Are those classes contained in another library (DLL, for example)?
It sounds like you need to recompile the entire application and see if that corrects the problem. Anytime a problem like this occurs, it is almost always a problem with the caller and callee's parameters having a mismatch. That can occur if all of the modules were not recompiled.
Also, if you debugged the assembly level, you can see exactly what is happening to your parameter of 4, and why it is being turned into a garbage value.
What I was thinking is that the SDL.DLL library is corrupting my own program memory, but I think it runs on another memory space. Anyone tried luck with Visual C+SDL?
Easy test -- just place that call that is giving you problems as the very first thing you do in main(), instead of making all of those other function calls. All that matters right now is to determine if it is a corruption problem:
Code:
int main()
{
CTerrain * tr = new CTerrain(384);
tr->generatePerlinNoise ( 4, 0.1 ); // does the 4 show up now?
delete tr;
}
Or this:
Code:
int main()
{
CTerrain tr(384);
tr.generatePerlinNoise ( 4, 0.1 );
}
When you use the debugger, does 4 show up in the function call?
Regards,
Paul McKenzie
-
December 30th, 2007, 02:39 AM
#3
Re: Member function parameter corruption ???
When I do not call the SDL function calls, I get a consistent value.
Code:
int main(int argc, char** argv)
{
CTerrain * tr = new CTerrain(384);
tr->generatePerlinNoise ( 4, 0.1 );
delete tr;
return 0;
}
Now I see 4.
Let's see the dissasembly, where we see the parameter being pushed into the stack as 4:
Code:
CTerrain * tr = new CTerrain(384);
00411F2E push 8
00411F30 call operator new (4114E7h)
00411F35 add esp,4
00411F38 mov dword ptr [ebp-0ECh],eax
00411F3E cmp dword ptr [ebp-0ECh],0
00411F45 je SDL_main+4Fh (411F5Fh)
00411F47 push 180h
00411F4C mov ecx,dword ptr [ebp-0ECh]
00411F52 call CTerrain::CTerrain (41116Dh)
00411F57 mov dword ptr [ebp-100h],eax
00411F5D jmp SDL_main+59h (411F69h)
00411F5F mov dword ptr [ebp-100h],0
00411F69 mov eax,dword ptr [ebp-100h]
00411F6F mov dword ptr [ebp-0F8h],eax
00411F75 mov ecx,dword ptr [ebp-0F8h]
00411F7B mov dword ptr [tr],ecx
tr->generatePerlinNoise ( 4, 0.1 );
00411F7E sub esp,8
00411F81 fld qword ptr [__real@3fb999999999999a (41E840h)]
00411F87 fstp qword ptr [esp]
00411F8A push 4
00411F8C mov ecx,dword ptr [tr]
00411F8F call CTerrain::generatePerlinNoise (411541h)
delete tr;
Now, let's see the old code...
***? I rebuilt the solution and I'm getting the correct value...
I'll work a bit on the code and i'll tell if it's eventually corrupted again.
What's the explanation for this?
Thank you!
-
December 30th, 2007, 05:11 AM
#4
Re: Member function parameter corruption ???
 Originally Posted by indiocolifa
What's the explanation for this?
Many IDE's don't put header-files into the dependancy lists of their build system.
So if you change signatures of functions in a header not all dependant modules are recompiled. This may have the effect that you described.
Kurt
-
December 30th, 2007, 11:16 PM
#5
Re: Member function parameter corruption ???
Well this is getting harsh. Now I'm getting corrupted variables on Release builds and NOT in Debug.
Compiler dissasembly on Debug (this is CORRECT):
Code:
extern "C" int main(int argc, char* argv[])
{
00411F70 push ebp
00411F71 mov ebp,esp
00411F73 sub esp,1A0h
00411F79 push ebx
00411F7A push esi
00411F7B push edi
00411F7C lea edi,[ebp-1A0h]
00411F82 mov ecx,68h
00411F87 mov eax,0CCCCCCCCh
00411F8C rep stos dword ptr es:[edi]
CGfxcore* gfxc = new CGfxcore();
00411F8E push 4
00411F90 call operator new (41150Ah)
00411F95 add esp,4
00411F98 mov dword ptr [ebp-18Ch],eax
00411F9E cmp dword ptr [ebp-18Ch],0
00411FA5 je SDL_main+4Ah (411FBAh)
00411FA7 mov ecx,dword ptr [ebp-18Ch]
00411FAD call CGfxcore::CGfxcore (4111F9h)
00411FB2 mov dword ptr [ebp-1A0h],eax
00411FB8 jmp SDL_main+54h (411FC4h)
00411FBA mov dword ptr [ebp-1A0h],0
00411FC4 mov eax,dword ptr [ebp-1A0h]
00411FCA mov dword ptr [ebp-198h],eax
00411FD0 mov ecx,dword ptr [ebp-198h]
00411FD6 mov dword ptr [gfxc],ecx
SDL_Event ev;
bool running = true;
00411FD9 mov byte ptr [running],1
atexit (SDL_Quit);
00411FDD push offset @ILT+60(_SDL_Quit) (411041h)
00411FE2 call @ILT+490(_atexit) (4111EFh)
00411FE7 add esp,4
if (!(gfxc->initialize(640,480,32)))
00411FEA push 20h
00411FEC push 1E0h
00411FF1 push 280h
00411FF6 mov ecx,dword ptr [gfxc]
00411FF9 call CGfxcore::initialize (41104Bh)
00411FFE movzx eax,al
00412001 test eax,eax
00412003 jne SDL_main+0F1h (412061h)
{
printf("Error initializing SDL\n");
00412005 mov esi,esp
00412007 push offset string "Error initializing SDL\n" (41E84Ch)
0041200C call dword ptr [__imp__printf (423584h)]
00412012 add esp,4
00412015 cmp esi,esp
00412017 call @ILT+1075(__RTC_CheckEsp) (411438h)
delete gfxc;
0041201C mov eax,dword ptr [gfxc]
0041201F mov dword ptr [ebp-174h],eax
00412025 mov ecx,dword ptr [ebp-174h]
0041202B mov dword ptr [ebp-180h],ecx
00412031 cmp dword ptr [ebp-180h],0
00412038 je SDL_main+0DFh (41204Fh)
0041203A push 1
0041203C mov ecx,dword ptr [ebp-180h]
00412042 call CGfxcore::`scalar deleting destructor' (411366h)
00412047 mov dword ptr [ebp-1A0h],eax
0041204D jmp SDL_main+0E9h (412059h)
0041204F mov dword ptr [ebp-1A0h],0
return -1;
00412059 or eax,0FFFFFFFFh
0041205C jmp SDL_main+2C0h (412230h)
}
CTerrain * tr = new CTerrain(384);
00412061 push 8
00412063 call operator new (41150Ah)
00412068 add esp,4
0041206B mov dword ptr [ebp-15Ch],eax
00412071 cmp dword ptr [ebp-15Ch],0
00412078 je SDL_main+122h (412092h)
0041207A push 180h
0041207F mov ecx,dword ptr [ebp-15Ch]
00412085 call CTerrain::CTerrain (411172h)
0041208A mov dword ptr [ebp-1A0h],eax
00412090 jmp SDL_main+12Ch (41209Ch)
00412092 mov dword ptr [ebp-1A0h],0
0041209C mov eax,dword ptr [ebp-1A0h]
004120A2 mov dword ptr [ebp-168h],eax
004120A8 mov ecx,dword ptr [ebp-168h]
004120AE mov dword ptr [tr],ecx
tr->generatePerlinNoise ( 1, 0.25 );
004120B1 sub esp,8
004120B4 fld qword ptr [__real@3fd0000000000000 (41E840h)]
004120BA fstp qword ptr [esp]
004120BD push 1
004120BF mov ecx,dword ptr [tr]
004120C2 call CTerrain::generatePerlinNoise (411564h)
Now ... Release build (total mess).
for example: argc -1414812757 ( !!!!!)
Code:
--- c:\documents and settings\hernan\mis documentos\visual studio 2008\projects\sdl1\sdl1\main.cpp
00401002 in al,dx
00401003 and esp,0FFFFFFC0h
00401006 sub esp,30h
00401009 push ebx
0040100A push ebp
0040100B push esi
0040100C push edi
CGfxcore* gfxc = new CGfxcore();
0040100D push 4
0040100F call operator new (4017D4h)
00401014 add esp,4
SDL_Event ev;
bool running = true;
atexit (SDL_Quit);
00401017 push offset SDL_Quit (401F7Eh)
0040101C mov ebp,eax
0040101E mov byte ptr [esp+27h],1
00401023 call atexit (4017B6h)
00401028 add esp,4
if (!(gfxc->initialize(640,480,32)))
0040102B push 100020h
00401030 call SDL_Init (401F6Ch)
00401035 add esp,4
00401038 test eax,eax
0040103A jne SDL_main+86h (401086h)
0040103C push 40000001h
00401041 push 20h
00401043 push 1E0h
00401048 push 280h
0040104D call SDL_SetVideoMode (401F72h)
00401052 add esp,10h
#endif
extern "C" int main(int argc, char* argv[])
{
CGfxcore* gfxc = new CGfxcore();
SDL_Event ev;
bool running = true;
atexit (SDL_Quit);
if (!(gfxc->initialize(640,480,32)))
{
printf("Error initializing SDL\n");
delete gfxc;
return -1;
}
CTerrain * tr = new CTerrain(384);
00401055 push 8
00401057 mov dword ptr [ebp],eax
0040105A call operator new (4017D4h)
0040105F mov esi,eax
00401061 xor ebx,ebx
00401063 add esp,4
00401066 cmp esi,ebx
00401068 je SDL_main+0C1h (4010C1h)
0040106A push 24000h
0040106F mov dword ptr [esi+4],180h
00401076 call operator new (4017D4h)
0040107B add esp,4
0040107E mov dword ptr [esi],eax
00401080 mov dword ptr [esp+28h],esi
00401084 jmp SDL_main+0C7h (4010C7h)
{
printf("Error initializing SDL\n");
00401086 push 403288h
0040108B call dword ptr [__imp__printf (4030F4h)]
00401091 add esp,4
delete gfxc;
00401094 test ebp,ebp
00401096 je SDL_main+0B6h (4010B6h)
00401098 mov eax,dword ptr [ebp]
0040109B test eax,eax
0040109D je SDL_main+0A8h (4010A8h)
0040109F push eax
004010A0 call SDL_FreeSurface (401F84h)
004010A5 add esp,4
004010A8 call SDL_Quit (401F7Eh)
004010AD push ebp
004010AE call operator delete (4017CEh)
004010B3 add esp,4
return -1;
004010B6 or eax,0FFFFFFFFh
while (running)
{
SDL_PollEvent(&ev);
if (ev.type == SDL_KEYDOWN)
if (ev.key.keysym.sym == SDLK_ESCAPE )
running = false;
//glClear(GL_COLOR_BUFFER_BIT);
SDL_Flip(gfxc->getSurface());
//SDL_GL_SwapBuffers();
}
delete gfxc;
delete tr;
return 0;
}
004010B9 pop edi
004010BA pop esi
004010BB pop ebp
004010BC pop ebx
004010BD mov esp,ebp
004010BF pop ebp
004010C0 ret
}
CTerrain * tr = new CTerrain(384);
004010C1 mov dword ptr [esp+28h],ebx
004010C5 mov esi,ebx
tr->generatePerlinNoise ( 1, 0.25 );
004010C7 fld qword ptr [__real@3fd0000000000000 (4032D0h)]
004010CD sub esp,8
004010D0 fstp qword ptr [esp]
004010D3 call CTerrain::generatePerlinNoise (4015B0h)
Maybe i'm getting problems with some optimizations by the compiler??
I will try to touch those settings are will post results.
-
December 30th, 2007, 11:18 PM
#6
Re: Member function parameter corruption ???
Seems that disabling 'Whole Program Optimization' which delays code generation until link-time solved the problem...
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|