C++ Question Variables going berserk ; searching a cause ??

N_Molson

Addon Developer
Addon Developer
Donator
Joined
Mar 5, 2010
Messages
10,002
Reaction score
4,418
Points
203
Location
Toulouse
Hello :hello:,

I'm experiencing something on my current project that already happened to me before and that is very frustrating.

Most of the variables I use (declared in the class/private part of the .h file, initialized in ClbkSetClassCaps) seem to be completely out of control. Some keep steady sometimes, but it is quite rare.

I'm using VC++2008, and the project was going rather smoothly, and then the hell got loose.

Here are the variables I declared, do you see anything wrong in this ? I used bool variables for the "do once" vars, but it seems that bool variables were the first affected, so I switched to int.

Code:
private:
    int done01, done02, done03, done04, done05; // those are "do once" variables
    int Shadow_i;
    int lights;

    double pVmem, yVmem, rVmem;
    double T0, T1;
    double MET, MET0;
    double BatteryChrg;
    double SPup_proc;
    double SPdn_proc;
    double SPle_proc;
    double SPri_proc;
    double ant_proc;

    UINT anim_SPup;
    UINT anim_SPdn;
    UINT anim_SPle;
    UINT anim_SPri;
    UINT anim_ant;

    char AntennaStatus[64];
    char SolarStatus[64];
    char ChrgStatus[64];
    char LightsStatus[64];

    SpotLight *docking_light;
};
And again, yes those variables are initialized.

What is really weird, is that it is not the first time it happens to me.

Also I have a problem with a TV tuner card that is not correctly working (already had this several months ago), and Windows ran a checkdisk on booting this morning (the same). All those events happened in less than 2 days, so it's hard to believe in coincidences...

I'm using Windows XP Pro SP3, which I re-installed a month ago, so it can't be OS-related...

Really, I don't get what is going wrong... Could I have somehow triggered a dangerous memory leak, and isn't VC++2008 supposed to keep safe from that ? :idk::idk:
 
So, what's wrong with those variables, because I can't see it? They appear very normal to me.
 
Let's not get ahead of ourselves and start panicking. Nothing can save you from memory leaks, but they also don't randomly appear because of nothing.

The variable declarations don't tell us a lot, but then neither will a massive code posting. It's unlikely to be hardware related (chckdisk is disk related, not memory and if you had a memory problem a whole-lot of other things would be going wrong).

In Visual studio you can set breakpoints for when memory values have been changed (rather than lines of code). Put a breakpoint in where your variable gets initialised and then when it breaks at that put a data-breakpoint (google this for instructions) for that variable. Execution should then break when that value is changed, allowing you to figure out where it is getting modified from.
 
Well, I really wonder. Taking the "do once" variables as an exemple, they are declared that way, seems pretty normal to me :

Code:
void Sigma_LES::clbkSetClassCaps (FILEHANDLE cfg)
{
	done01 = 0;
	done02 = 0;
	done03 = 0;
	done04 = 0;
	done05 = 0;

But if I run an "oapiDebugString", I got incoherent readings, especially for "done02" & "done03" :

done02 : 87806344
done03 : 87806200

And the only place they are used in the code is there :

Code:
	if (MET > 30 && done02 == 0)
	{
		Revert_ant(); // triggers animation
		done02 = 1;
	}

	if (MET > 60 && done03 == 0)
	{
		Revert_SPup();
		Revert_SPdn(); // triggers animations
		done03 = 1;
	}

MET (double) is a timer that works correctly.
 
Last edited:
Generally initialization is better placed in the class' constructor. Do you use "safe" versions of all string routines?
 
Have you put a data-breakpoint in? It's most likely that you've got a floating pointer or string routines are writing to the wrong area of memory

---------- Post added at 15:07 ---------- Previous post was at 15:02 ----------

Is it possible that you've got more than one instantiation of your class and you initialise the variables in one object and get them via oapiDebugString from the other? Also, how are you using oapiDebugString? Make sure that you use sprintf with it and don't just use oapiDebugString(done02);
 
Generally initialization is better placed in the class' constructor. Do you use "safe" versions of all string routines?

I just put the variables in the class constructor. It looks better organized, but changes nothing. What is a "safe" version of a string routine ?

if you had a memory problem a whole-lot of other things would be going wrong

The fact is I have 4GB RAM DDR3 installed, and that Windows only recognizes 3GB... But the checksum at bootup is OK. :idk:

Have you put a data-breakpoint in? It's most likely that you've got a floating pointer or string routines are writing to the wrong area of memory

Well, I fear it is going to take me a few days to understand how to do that... The "data breakpoint" command in the "Debug" menu is gray, seems I can't use it.

Is it possible that you've got more than one instantiation of your class and you initialise the variables in one object and get them via oapiDebugString from the other?

Only 1 vessel, Mir & the ISS in my test scenario.

Also, how are you using oapiDebugString?

Like this :

Code:
sprintf(oapiDebugString(), "MET %.2f | done01 %i | done02 %i | done03 %i | done04 %i | done05 %i", MET, done01, done02, done03, done04, done05);
 
Last edited:
sprintf_s and other "safe" functions with the _s suffix are presumed to check for buffer length and never overwrite stuff beyond the buffer.

EDIT: it may well be a memory error (had a fried DRAM chip once), but you have to look for other random crashes in other applications, or use hardware diagnostics suites.
 
Last edited:
The fact is I have 4GB RAM DDR3 installed, and that Windows only recognizes 3GB... But the checksum at bootup is OK. :idk:
Are you running 32-bit? I think that 32-bit Windows can only handle 3GB.

Well, I fear it is going to take me a few days to understand how to do that... The "data breakpoint" command in the "Debug" menu is gray, seems I can't use it.
You're probably running in release mode. Look in 'configurations' and you should see 'Debug' as well as 'Release'. Change it to debug. Then hit F5 to run it. It will ask for an executable --> Point it to orbiter. If you get an empty launchpad then exit orbiter and go to (I think) Project --> Configurations and select your 'Debug' configuration. There will be an option somewhere for debugging. In there you will see that the target executable is set to be orbiter.exe. There is also a target path (or something like this). Set that to be the orbiter directory and then OK, OK etc. Hit F5 to run in the debugger. You should be able to enter breakpoints in your code to stop and inspect variables at runtime.
 
I understood the data-breakpoint thing and tracked down that nasty bug. :thumbup:

It was related to a beaconlight declaration in SetClassCaps, used with a [i++] thing... Probably overwrote the memory of the done02 & done03 variables... Weird... :shifty:

Thanks for the support ! :tiphat:
Are you running 32-bit? I think that 32-bit Windows can only handle 3GB.

Yes. Thanks for the info. Seems that the vendor that sold me the RAM "forgot" to tell me that. :dry:
 
You triggered the [ame="http://en.wikipedia.org/wiki/Undefined_behavior"]Undefined behavior - Wikipedia, the free encyclopedia[/ame] . Anything can happen then, including launching another instance of Orbiter with your plugin activated, and so on :)
 
... and precisely, it was an array of 6 elements with an incorrect size declaration :

Code:
for (j = 0; j < 7; j++) {

instead of :

Code:
for (j = 0; j < 6; j++) {

Seems I forgot the 0. :facepalm:

But I'm surprised how much a little thing can break havoc on all the code. :blink:

Sounds like you merrily fell off the end of the array and carried on writing over whatever was next in the memory space, which happened to be these variables.

Exactly !

You triggered the Undefined behavior. Anything can happen then, including launching another instance of Orbiter with your plugin activated, and so on

That means that this error might have corrupted my TVtuner card settings, provided it points to that memory adress ?!? :shifty: Isn't a safeguard in the CPU or elsewhere supposed to avoid that ?
 
Last edited:
That means that this error might have corrupted my TVtuner card settings, provided it points to that memory adress ?!? :shifty: Isn't a safeguard in the CPU or elsewhere supposed to avoid that ?
[ame="http://en.wikipedia.org/wiki/Virtual_memory"]Virtual Memory[/ame] mapping prevents your (buggy) code interfering with other areas of the physical memory, including other programs, the OS itself and device drivers. This is specifically to prevent you crashing other programs or the OS. The worst thing you can (normally!) do is to just crash your own program.

---------- Post added at 16:18 ---------- Previous post was at 16:13 ----------

... and precisely, it was an array of 6 elements with an incorrect size declaration :

Code:
for (j = 0; j < 7; j++) {
instead of :

Code:
for (j = 0; j < 6; j++) {
Seems I forgot the 0. :facepalm:
This is exactly why I always discourage the inclusion of 'magic numbers' in code. In all code that I do, unless there is a very good reason I never include hard-coded numbers/strings in the main section of code. I always reference them by a variable, sizeof command or a #define:

Code:
#define SIZE   6
...
int array[SIZE];
for(int i = 0; i < SIZE; i++)
   array[i] = i;


int newsize = 9;
int newarray[] = new int[newsize];
for(int i = 0; i < newsize; i++)
    newarray[i] = i;

(or rarely)
int thirdarray[4];
for(int i = 0; i < sizeof(thirdarray); i++)
   thirdarray[i] = i;
 
Last edited:
That means that this error might have corrupted my TVtuner card settings, provided it points to that memory adress ?!? :shifty: Isn't a safeguard in the CPU or elsewhere supposed to avoid that ?
Normally the programs are isolated from each other and from the drivers, so a dangling pointer or buffer overrun cannot damage the data in another program. It's a fundamental property of every modern OS on every modern CPU (1970+ general, 1990+ for PC, 2000+ for Microsoft stuff).

So the TV card is likely an unrelated coincidence.
(Speaking blindly out of common sense)
 
So the TV card is likely an unrelated coincidence.
(Speaking blindly out of common sense)

Yeah, I'm very very suspicious about it, because it already happened a couple of times while struggling to run C++ projects. The probabilities that it is unrelated are probably neglectible.

Probably just a weird hardware-software incompatibility problem ! :rolleyes:
 
The problem with a TV card involved is that there are dozens of other factors that are suspect too... Like a loose TV plug, (severe) static electricity in the TV line, etc... Yeah the computer is plugged to the ground (if the ground plug is linked to something), in theory... Even worse, I have an hybrid TV card (analog/BDA), that I want to work in DBVT mode, so, yeah, it's a real mess... But it was working well the last 6 months.

The memory chips are fine, I'm sure of that.
 
Back
Top