Hello everybody,
I wrote a program that can save some data into file and then read it from there,the weird thing is that it loads correctly from the file only when it's in debbug mode,and doesn't do it at all when it in release mode.
Here are the code fragment:

int extantion (char *buf)
{
	int i;
	for(i=0;((buf[i]!=NULL)&&(buf[i]!='.'));i++)  ;
	switch(buf[i])
	{
	case NULL:
		{
		buf[i]='.';
		buf[i+1]='s';
		buf[i+2]='a';
		buf[i+3]='v';
		buf[i+4]=NULL;
	
		return 1;
		}
		
	case '.':
		if((buf[i+1]=='s')&&(buf[i+2]=='a')&&(buf[i+3]=='v'))
					return 1;
		
		else
		{
			MessageBox(NULL,"Wrong extantion!"," message:",MB_OK);
			return 0;
		}
		
	}
}

 
void SAVE (char *buf)
{
	int i;
	char *savename;
	savename=buf;
ofstream savfile;
if((extantion(savename))==0) return;
savfile.open(savename);
savfile<<"SF"<<" ";
 for(i=0;i<81;i++)
 {
 savfile<<save[i]<<" ";
 }
savfile.close();
}
 
void LOAD(char *buf)
{
int i,check;
char ver[4];
char *loadname;
ifstream loadfile;
loadname=buf;


if((check=extantion(loadname))==0) return;
loadfile.open(loadname);
loadfile>>ver; 
if(ver[0]=='S')&&(ver[1]=='F'))
  {
   for(i=0;i<81;i++) loadfile>>save[i];
    loadfile.close();
  succes='t';
  }
  
  else
  {
    MessageBox(NULL,"The file you want to load is not a Music Generator save file,or it doesn't exist!\n Action canceled.","Music Generator message:",MB_OK);
    loadfile.close();
	succes='f';

  }
}

Can anyone explain to me please why the program doesn't load correctly when it's in release mode?
p.s.
I use VC++ 6.0

Are you even using the FUNCTIONS in a main program.. in C/C++ you need to implement them in main() i.e.

int main( int argc, const char* argv[] )
{
// CODE HERE..
}

I'm confused as to what you are doing here to be quite honest, how are you getting the data to save/load to the files? There are a number of problems I could find out but maybe its best to stick to the question in hand..

Edited 3 Years Ago by diafol: fixed formatting

ofcourse I have a main function.
My program is an API program ,so my main function looks like this:

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
...
...
...
...
}

and before you try to find problems in the main function,I hurry to tell you that the programs compiles and builds very well,it doesn't give
any errors.
in my program I use couple of dialogs.
A main dialog and a save/load dialog.
Here is the part of the main dialog that calls the save/load dialog:

case IDC_SAVEBUTTON:
			 option='s';
			 DialogBox(MainWind,MAKEINTRESOURCE(IDD_DIALOGSAVE),hwnd,SaveloadDlgProc);
			 break;
		 case IDC_LOADBUTTON:
            option='l';
			 DialogBox(MainWind,MAKEINTRESOURCE(IDD_DIALOGSAVE),hwnd,SaveloadDlgProc);
			 if(succes=='t')SetDlgItemText(hwnd,IDC_PAGAIN," Loaded");
			 break;

and here is the part of the save/load dialog that calls the save or load function(depends on the option variable):

case IDOK:
			{
			    int len=GetWindowTextLength(GetDlgItem(hwndsl,IDC_SAVELOAD));
				 if(len>0)
				 {
					
					buf=(char *)GlobalAlloc(GPTR,len+5);
                   GetDlgItemText(hwndsl, IDC_SAVELOAD, buf, len + 5);
				 }
		 	    switch(option)
				  {
				    case 's':
					if(buf==NULL)
					{
						MessageBox(hwndsl,"Please enter the file name!","Request:",MB_OK);
						goto  endmark;
					}

						SAVE(buf);
                                  endmark:
					break;
				    case 'l':
                       if(buf==NULL)
					   {
						MessageBox(hwndsl,"Please enter the file name!","Request:",MB_OK);
						goto endmark2;
					   }
					LOAD(buf);
					
                                  endmark2:
					break;
				  }
				  GlobalFree((HANDLE) buf);
				  EndDialog(hwndsl,0);
					}//End of IDOK case
			break;

(the option variable is global)
as I already told,the problem is that when in debbug mode
the program writes to files and reads from files with no problems.
But when in release mode it doesn't read from the file(still can write to it normaly,but doesn't read),no error messages apear,but the data in the array doesn't change.

Well bops,what are those problems you could think of??
I'm pretty sure that I'm not the first one who ecountered a problem with the VC++ 6.0 compiler(the compiler is pretty popular).
And I'm sure not the first one who had a problem while moving from "debbug" to "release", any advice?(that has to do with the kind of dysfunction I described)


Thanks to everyone who try to help,
A.

Wrong, vc++ 6.0 is horrible, no one who programs seriously uses it I'm afraid.

You should update to at least vc++ 2005. I think you can download the windows sdk separately with the express edition, or so I've heard?

iamthwee,thank you for the advice,when I will have the opportunity I will get another compiler BUT in the mean time
it's the only compiler I can get my hands on ,so I don't realy have much choice(Anyway I think the problem is more about some technical detail I don't know about and it can be solved)
I checked the bad() flag ( loadfile.bad() ) and it returned true
in release mode,indicating that the 'reading from file' operation failed.
So I repeat the question: What can cause the 'reding from file' operation to fail in the release mode?(in the debbug mode it works good)(maybe some files are added automaticly in debbug and I need to add them manualy in release,or maybe it has something to do with the compiling proccess,any help appreciated...)

In VC 6.0++ each of Debug & Release can have different settings for directories. Use ALT-F7 and check that the settings for each is the same

Thanks for your help everybody,
iamthwee,thanks for the links(already read some of them before,and
read the other ones today).
Tight_Coder_Ex,I know about the "settings" option, but I didn't quite understand you,what 'directories settings' are you talking about and where in the "settings" menu do I find them?

I did some more expirements with the program today and found out something weird,it seems that it only has a problem with reading from files when it reads into a "floating point variable" (double,float...)
(in release mode that is),why can it happen?

(the program reads the "SF" in the beggining of the file and puts it into
a char array with no problems.
And when I replace the double variables with integer ones it suddenly beggins to work(there is a huge bug with that,but it works) ,maybe somebody can explain?)

I did some more expirements with the program today and found out something weird,it seems that it only has a problem with reading from files when it reads into a "floating point variable" (double,float...)
(in release mode that is),why can it happen?

You can invoke the debugger in release mode too. Trace that part of the program and see if an optomization setting is causing a problem.

It doesn't sound like my contention of the directories is the problem

And when I replace the double variables with integer ones it suddenly beggins to work(there is a huge bug with that,but it works) ,maybe somebody can explain?)

The only way this can happen is the file contains integers, not doubles.

> for(i=0;i<81;i++) loadfile>>save;
What is save ?


buf=(char *)GlobalAlloc(GPTR,len+5);
                   GetDlgItemText(hwndsl, IDC_SAVELOAD, buf, len + 5);
				 }
		 	    switch(option)
				  {
				    case 's':
					if(buf==NULL)
					{
						MessageBox(hwndsl,"Please enter the file name!","Request:",MB_OK);
						goto  endmark;
					}

						SAVE(buf);
                                  endmark:

1. You ignore return results
2. You use a pointer, THEN later on test it for NULL
3. Your use of goto is an abomination for if ( ) else
4. When you post code, you need to replace ALL your tabs with spaces (or just set your IDE to always indent using spaces). Everything will line up nicely then. Don't rely on HTML rendering tabs at whatever tab-stops you've chosen in your editor.

Tight_Coder_Ex wrote:

You can invoke the debugger in release mode too. Trace that part of the program and see if an optomization setting is causing a problem.

It doesn't sound like my contention of the directories is the problem

it did in the beggining,but I turned optimization off.
about the directories,maybe they are not the problem ,but I still want to know about them.

WaltP wrote:

The only way this can happen is the file contains integers, not doubles.

BUT it contains doubles my friend(the numbers have floating point).

Salem wrote:

> for(i=0;i<81;i++) loadfile>>save;
What is save ?

save is a global variable,it's an array of type double and size 81,and before you ask,YES I set it to zeros
in the beggining of my program.

Salem wrote:

1. You ignore return results
2. You use a pointer, THEN later on test it for NULL
3. Your use of goto is an abomination for if ( ) else
4. When you post code, you need to replace ALL your tabs with spaces (or just set your IDE to always indent using spaces). Everything will line up nicely then. Don't rely on HTML rendering tabs at whatever tab-stops you've chosen in your editor.

1. Why is it a problem in my case?(I don't think it can cause the problem I described).
2. Why is it wrong?
3. Actualy the only way to use goto is with a condition(and guess what's if() is),and besides it won't cause a file reading problem(if I unerstand wrong please correct me).
4. Thanks,I will replace in the future.

And now about one more expirement I did with the program.
My save files are actualy text files(I can open the file with notepad and just read the numbers as text),so I thought that maybe when reading from file, the compiler see the data it reads as strings.
So instead of loading the data directly into a double variable
I loaded it into a char array first and then converted it to a number
using stringstream().
The good part is that the bad() flag stopped returning 'true'.
The bad part is that the data still didn't arrive to the 'save' array
(the array remained filled with zeros).

2. You use a pointer, THEN later on test it for NULL

2. Why is it wrong?

NULL means that the pointer doesn't point to anything, so using a pointer and testing it for NULL afterwards is an entirely backwards way of doing things. Consider this scenario at breakfast time -

pour_milk( glass );
if( glass == NULL )
    //Too late, we've already poured the milk, and its gone all over the 
    //  floor, because we didn't check the glass was there before pouring!
if ( glass == NULL )
    //The glass isn't there, better get one out of the cupboard
else
    pour_milk( glass );  //That's better, we know that a glass exists.

Bench,thank you for the example BUT I don't use the pointer before I check it!
The use of the pointer happens when I call the SAVE() function:

SAVE(buf);

And I check for NULL before that.

Salem just didn't notice that I switch the 'option' variable
and note the 'buf' pointer.

When I asked "what's wrong with that?",I meant :"What's wrong with checking for NULL?".

buf='.';
buf[i+1]='s';
buf[i+2]='a';
buf[i+3]='v';

Another thing worth mentioning is the somewhat infantile method you have for comparing/initialising c-style strings. (I hope you don't mind me saying) that personally I think you need to look at some of the newbie tutorials.

In will be well worth it.

iamthwee wrote:

Another thing worth mentioning is the somewhat infantile method you have for comparing/initialising c-style strings. (I hope you don't mind me saying)

Acctualy I do mind!
You wasn't much help from the beggining of this thread,but you don't see me calling you infantile!!!
On the contrary I was very polite.
I wrote the mentioned piece of code in a primitive way on purpose,
the compiler gave me trouble when I tried to do it in other ways.

You need to read all the comments in this thread very carefully. We are trying to help you, but you seem to take the criticisms personally?

> buf=(char *)GlobalAlloc(GPTR,len+5);
> GetDlgItemText(hwndsl, IDC_SAVELOAD, buf, len + 5);
> ...
> if(buf==NULL)
It surely looks like you're using it before checking it to me.

> 1. Why is it a problem in my case?(I don't think it can cause the problem I described).
Let's see - your code doesn't work, and you assume success.
Tell me where the logical fallacy in your argument is.
Take every opportunity to check status results, so you get immediate and to the point diagnosis of a problem. As opposed to the code stumbling on for a while with garbage data and eventually failing for some non-related or less than obvious problem.

Does (for example) GetDlgItemText() always append a \0 ?
If not, then you're trying to open a filename with random garbage at the end.


> 3. Actualy the only way to use goto is with a condition
What's wrong with

if(buf==NULL)
{
    MessageBox(hwndsl,"Please enter the file name!","Request:",MB_OK);
}
else
{
    SAVE(buf);
}

Perhaps before you open the file, you could try loadfile.clear();

Comments
It looks that way to me too, unless his code formatting is that bad

Salem wrote:

> buf=(char *)GlobalAlloc(GPTR,len+5);
> GetDlgItemText(hwndsl, IDC_SAVELOAD, buf, len + 5);
> ...
> if(buf==NULL)
It surely looks like you're using it before checking it to me.

Yes,you are absolutely right, I am a little scattered,ain't I.
I will fix that piece of code.

Thanks for the other advice too,I realy appreciate it.

This article has been dead for over six months. Start a new discussion instead.