Release crashes but debug works.
-
Hi, When I compile my program as a release it crashes when I try to run it. However the debug version works. It doesn't give any specific errors. Any suggestions? Thanks.
Cyclone_S wrote:
Any suggestions?
yes, three of them: 1. make sure you have adequate problem logging within your app; every exception should be logged; every API call should have its return value checked, and abnormalities need logged. 2. read Surviving the Release Version[^] 3. read Debugging Release Mode Problems[^] :)
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
Hi, When I compile my program as a release it crashes when I try to run it. However the debug version works. It doesn't give any specific errors. Any suggestions? Thanks.
none at all? are you sure you get absolutely no errors? even if not specific, post them and that'll give us a clue as to the problem. the debug software version does a few things differently so that the software doesn't crash immediately following an error, to allow for debugging. one such case is accessing an out of bounds location within an array, either to read or write... the release version would crash immediately, the debug version might not (will likely be caught with an ASSERT of some sort).
-
Cyclone_S wrote:
Any suggestions?
yes, three of them: 1. make sure you have adequate problem logging within your app; every exception should be logged; every API call should have its return value checked, and abnormalities need logged. 2. read Surviving the Release Version[^] 3. read Debugging Release Mode Problems[^] :)
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
good links luc... we replied almost simultaneously...
-
none at all? are you sure you get absolutely no errors? even if not specific, post them and that'll give us a clue as to the problem. the debug software version does a few things differently so that the software doesn't crash immediately following an error, to allow for debugging. one such case is accessing an out of bounds location within an array, either to read or write... the release version would crash immediately, the debug version might not (will likely be caught with an ASSERT of some sort).
Thanks for your reply. I found the function that crashes the Release version. I get the error "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." So it's either MyArray[50] that crashes it or the string builders.
void Read_Text() { char ch; int i; char MyArray[50]; ifstream in("scores.ini", ios::in | ios::binary); // Open the file for binary operations. while(in && ch) // Read data from file untill the end of the file is reached. { // "in" will be false if the end of the file has been reached. i++; in.get(ch); if(in) {MyArray[i-1] = ch;} } in.close(); // Close the file after the file date has been read. // Score # 1 StringBuilder^ sbA = gcnew StringBuilder(); int iA = 0; for(iA;MyArray[iA] != '_';iA++) // Score { sbA->Append((Char)MyArray[iA]); } String^ s = sbA->ToString(); // Convert the first score into an integer to compare with the current score. score1 = Convert::ToInt32(s); // Score # 2 StringBuilder^ sbB = gcnew StringBuilder(); int iB = iA+1; for(iB;MyArray[iB] != '_';iB++) // Score { sbB->Append((Char)MyArray[iB]); } String^ sB = sbB->ToString(); // Convert the Second score into an integer to compare with the current score. score2 = Convert::ToInt32(sB); // Score # 3 StringBuilder^ sbC = gcnew StringBuilder(); int iC = iB+1; for(iC;MyArray[iC] != '_';iC++) // Score { sbC->Append((Char)MyArray[iC]); } String^ sC = sbC->ToString(); // Convert the Second score into an integer to compare with the current score. score3 = Convert::ToInt32(sC); // Score # 4 StringBuilder^ sbD = gcnew StringBuilder(); int iD = iC+1; for(iC;MyArray[iD] != '_';iD++) // Score { sbD->Append((Char)MyArray[iD]); } String^ sD = sbD->ToString(); // Convert the Second score into an integer to compare with the current score. score4 = Convert::ToInt32(sD); if(show_msge==true){MessageBox::Show("Top Scores\n" + Convert::ToString(score1) + "\n" + Convert::ToString(score2) + "\n"+ Convert::ToString(score3) + "\n" + Convert::ToString(score4));} }
-
Thanks for your reply. I found the function that crashes the Release version. I get the error "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." So it's either MyArray[50] that crashes it or the string builders.
void Read_Text() { char ch; int i; char MyArray[50]; ifstream in("scores.ini", ios::in | ios::binary); // Open the file for binary operations. while(in && ch) // Read data from file untill the end of the file is reached. { // "in" will be false if the end of the file has been reached. i++; in.get(ch); if(in) {MyArray[i-1] = ch;} } in.close(); // Close the file after the file date has been read. // Score # 1 StringBuilder^ sbA = gcnew StringBuilder(); int iA = 0; for(iA;MyArray[iA] != '_';iA++) // Score { sbA->Append((Char)MyArray[iA]); } String^ s = sbA->ToString(); // Convert the first score into an integer to compare with the current score. score1 = Convert::ToInt32(s); // Score # 2 StringBuilder^ sbB = gcnew StringBuilder(); int iB = iA+1; for(iB;MyArray[iB] != '_';iB++) // Score { sbB->Append((Char)MyArray[iB]); } String^ sB = sbB->ToString(); // Convert the Second score into an integer to compare with the current score. score2 = Convert::ToInt32(sB); // Score # 3 StringBuilder^ sbC = gcnew StringBuilder(); int iC = iB+1; for(iC;MyArray[iC] != '_';iC++) // Score { sbC->Append((Char)MyArray[iC]); } String^ sC = sbC->ToString(); // Convert the Second score into an integer to compare with the current score. score3 = Convert::ToInt32(sC); // Score # 4 StringBuilder^ sbD = gcnew StringBuilder(); int iD = iC+1; for(iC;MyArray[iD] != '_';iD++) // Score { sbD->Append((Char)MyArray[iD]); } String^ sD = sbD->ToString(); // Convert the Second score into an integer to compare with the current score. score4 = Convert::ToInt32(sD); if(show_msge==true){MessageBox::Show("Top Scores\n" + Convert::ToString(score1) + "\n" + Convert::ToString(score2) + "\n"+ Convert::ToString(score3) + "\n" + Convert::ToString(score4));} }
wow, guess i'll start from the top: - the initial statement
while(in && ch)
never hasch
initialize - indexi
never gets initialized - are you checking for underscores? what happens if there's no underscore in your loop? runs until program breaks... - you never check if any indexes will write out of bounds of the array those are just some observations... and I didn't even bother going through it all because its so bad -
Thanks for your reply. I found the function that crashes the Release version. I get the error "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." So it's either MyArray[50] that crashes it or the string builders.
void Read_Text() { char ch; int i; char MyArray[50]; ifstream in("scores.ini", ios::in | ios::binary); // Open the file for binary operations. while(in && ch) // Read data from file untill the end of the file is reached. { // "in" will be false if the end of the file has been reached. i++; in.get(ch); if(in) {MyArray[i-1] = ch;} } in.close(); // Close the file after the file date has been read. // Score # 1 StringBuilder^ sbA = gcnew StringBuilder(); int iA = 0; for(iA;MyArray[iA] != '_';iA++) // Score { sbA->Append((Char)MyArray[iA]); } String^ s = sbA->ToString(); // Convert the first score into an integer to compare with the current score. score1 = Convert::ToInt32(s); // Score # 2 StringBuilder^ sbB = gcnew StringBuilder(); int iB = iA+1; for(iB;MyArray[iB] != '_';iB++) // Score { sbB->Append((Char)MyArray[iB]); } String^ sB = sbB->ToString(); // Convert the Second score into an integer to compare with the current score. score2 = Convert::ToInt32(sB); // Score # 3 StringBuilder^ sbC = gcnew StringBuilder(); int iC = iB+1; for(iC;MyArray[iC] != '_';iC++) // Score { sbC->Append((Char)MyArray[iC]); } String^ sC = sbC->ToString(); // Convert the Second score into an integer to compare with the current score. score3 = Convert::ToInt32(sC); // Score # 4 StringBuilder^ sbD = gcnew StringBuilder(); int iD = iC+1; for(iC;MyArray[iD] != '_';iD++) // Score { sbD->Append((Char)MyArray[iD]); } String^ sD = sbD->ToString(); // Convert the Second score into an integer to compare with the current score. score4 = Convert::ToInt32(sD); if(show_msge==true){MessageBox::Show("Top Scores\n" + Convert::ToString(score1) + "\n" + Convert::ToString(score2) + "\n"+ Convert::ToString(score3) + "\n" + Convert::ToString(score4));} }
a couple of other things... this is managed C++, belongs in the C++/CLI forum... what happens if your open file fails? the function will lead to a program crash since you have no error handling... i really hope this is just pseudo-code and not your real thing, if its your real thing, you may want to take a step back to the basics.
-
Hi, When I compile my program as a release it crashes when I try to run it. However the debug version works. It doesn't give any specific errors. Any suggestions? Thanks.
As a rule of thumb, I found that most crashes that only happen in release versions are due to lack of intialization: In debug mode, all variables are initialized with 0 by default. In release mode, this is not the case. Specifically for pointers this can have disastrous consequences, e. g. when you test try to delete an object from a non-null pointer which presumably points to an object created by new. The best way to avoid these type of errors is to always explicitely initialize a variable on the same line that declares them. The best way to treat with these errors is locate the part of the code that causes it, and make sure every variable is properly initialized.
-
wow, guess i'll start from the top: - the initial statement
while(in && ch)
never hasch
initialize - indexi
never gets initialized - are you checking for underscores? what happens if there's no underscore in your loop? runs until program breaks... - you never check if any indexes will write out of bounds of the array those are just some observations... and I didn't even bother going through it all because its so badAlbert Holguin wrote:
- index
i
never gets initializedMy bet is on that one. :) I agree that there are many other problems, e. g. it should be just
while (in)
sincech==0
is a valid input. Also, why not use>>
operators rather thanget()
? Besides, @OP, use the <pre> tags to format a block of code, not <code>. -
Albert Holguin wrote:
- index
i
never gets initializedMy bet is on that one. :) I agree that there are many other problems, e. g. it should be just
while (in)
sincech==0
is a valid input. Also, why not use>>
operators rather thanget()
? Besides, @OP, use the <pre> tags to format a block of code, not <code>.don't know if I'd agree with using
>>
instead ofget()
, but there's a lot of problems in that code either way. i hope this is OP's homework and not work. -
don't know if I'd agree with using
>>
instead ofget()
, but there's a lot of problems in that code either way. i hope this is OP's homework and not work.My point of using
>>
is that you can read a variable with just one command rather than put it together byte by byte. It might be difficult though to change the code, depending on the complexity of the data structure within that file. Also, the data in that file have to be stored in the right way, i. e. using<<
, to make sure they will be properly read using>>
. If all you ever use fromifstream
isget()
, then I have to ask, why use ifstream at all? That's like using MS Word for SMS... ;) -
My point of using
>>
is that you can read a variable with just one command rather than put it together byte by byte. It might be difficult though to change the code, depending on the complexity of the data structure within that file. Also, the data in that file have to be stored in the right way, i. e. using<<
, to make sure they will be properly read using>>
. If all you ever use fromifstream
isget()
, then I have to ask, why use ifstream at all? That's like using MS Word for SMS... ;)>>
is not type safe and reading incorrect input type leads to undefined behavior -
>>
is not type safe and reading incorrect input type leads to undefined behaviorSame with bytewise input: you just delay the problem from the reading part to the interpreting part. In either case you have to somehow validate the resulting values. Unfortunately this is almost impossible with binary inputs, and for that reason alone I'd retract my suggestion of using
>>
here. -
As a rule of thumb, I found that most crashes that only happen in release versions are due to lack of intialization: In debug mode, all variables are initialized with 0 by default. In release mode, this is not the case. Specifically for pointers this can have disastrous consequences, e. g. when you test try to delete an object from a non-null pointer which presumably points to an object created by new. The best way to avoid these type of errors is to always explicitely initialize a variable on the same line that declares them. The best way to treat with these errors is locate the part of the code that causes it, and make sure every variable is properly initialized.
Well you guys were right about not initializing those variables. That fixed the problem. Thanks. I'm not sure what's wrong with my code. How would you re-write it. I'm checking for under scores to check for the next score. The file looks like this: 100_ 200_ 300_ 400_
-
a couple of other things... this is managed C++, belongs in the C++/CLI forum... what happens if your open file fails? the function will lead to a program crash since you have no error handling... i really hope this is just pseudo-code and not your real thing, if its your real thing, you may want to take a step back to the basics.
-
Well you guys were right about not initializing those variables. That fixed the problem. Thanks. I'm not sure what's wrong with my code. How would you re-write it. I'm checking for under scores to check for the next score. The file looks like this: 100_ 200_ 300_ 400_
Wait, are you saying you're reading a standard ASCII text file? :confused: If so, why bother reading it as binary, byte by byte? Just open a normal file stream and use its standard operator >> to stream the numbers into your variables. Try these functions to write and read your
void WriteScores(const std::vector& scores) {
int nscores = (int) scores.size();
std::ofstream scorestream("Myscores.txt");
scorestream << nscores; // write number of entries
for (int i=0; i < nscores; ++i)
scorestream << ' ' << scores[i]; // write entries, using blank (' ') as separator
}
int ReadScores(std::vector& scores) {
int nscores = 0;
std::ifstream scorestream("Myscores.txt");
scorestream >> nscores;
scores.resize(nscores);
for (int i=0; i < nscores; ++i)
scorestream >> scores[i];
return nscores;
}You may want to add in some extra code to check for premature end of file or failure to create/write or read the file. You might also want to check the state of the filestream after reading each number to make sure an actual integer was read (if there was no integer, the resulting value will be 0, but since 0 may be a valid value, you can check on the state of your stream variable instead)