9 replies to this topic
#1 Members - Reputation: 141
Posted 06 October 2012 - 06:10 PM
I was just writing a small program today converting csv files to xml, and I noticed something weird was happening. I had an array of doubles that was being iniatialized near the end of the program using an array of strings, atof(), and a for loop. When I commented out the initialization and left only the declaration, I got some runtime errors. Then when I commented out the declaration, the program ran fine again. I've never had this happen to me before, so I made a short test program. All it was was an integer declaration, and it ran fine. Any idea what's causing this?
#2 Moderators - Reputation: 10534
Posted 06 October 2012 - 06:21 PM
When your program relies on undefined behaviour, changing the generated code or the runtime memory layout, even in an unrelated areas, can suddenly reveal latent bugs elsewhere.
#3 Crossbones+ - Reputation: 18775
Posted 06 October 2012 - 06:47 PM
If you are lucky, it will be the type of thing that crashes systematically. Try to find the simplest program that still has the crash, and then post it here.
#4 Members - Reputation: 141
Posted 06 October 2012 - 07:48 PM
#include <iostream> #include <string> #include <cstdio> #include <cstdlib> using namespace std; const int CELLS_IN_GRID = 81; int main() { FILE *file; /* Pointer to File */ double cellValue[CELLS_IN_GRID]; /* Array of cellValues for each Cell in Grid */ string csvValue[CELLS_IN_GRID]; /* Array of cellValues as Strings */ char currentChar; /* Current Character in File Stream */ int cellPosition = 0; string filename; cin >> filename; file = fopen(filename.c_str(), "r"); while(currentChar != EOF) { currentChar = fgetc(file); if(currentChar != ',' && currentChar != '%') { csvValue[cellPosition] += currentChar; } if(currentChar == ',') { cellPosition++; } } fclose(file); /*for(int i=0;i<CELLS_IN_GRID;i++) { //cellValue[i] = atof(csvValue[i].c_str()); //cout << csvValue[i] << '%' << " " << i << endl; }*/ return 0; }Here's the code. The line that causes it to break(if commented out) is the first line in the for loop.
Edited by Captacha, 06 October 2012 - 08:14 PM.
#5 Crossbones+ - Reputation: 18775
Posted 06 October 2012 - 08:32 PM
Can you not reproduce the problem without reading an external file? Can you give us a sample external file to reproduce the problem?
#6 Members - Reputation: 1609
Posted 06 October 2012 - 08:46 PM
Maybe throw an assert in checking that cellPosition < CELLS_IN_GRID.
#7 Crossbones+ - Reputation: 4832
Posted 06 October 2012 - 11:45 PM
Also, initialise currentChar to a value != EOF. That could potentially skip your reading loop.
Check if cellPosition gets >= CELLS_IN_GRID. If it does you're writing in memory that is not yours. Once that happens all kind of weird things can happen (hence undefined).
The lines inside the for loop look ok.
Check if cellPosition gets >= CELLS_IN_GRID. If it does you're writing in memory that is not yours. Once that happens all kind of weird things can happen (hence undefined).
The lines inside the for loop look ok.
Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>
#8 Crossbones+ - Reputation: 18775
Posted 07 October 2012 - 06:52 AM
This is how I typically make a loop for reading from a file:
In the case of reading character by character (which perhaps you should reconsider), it looks like this:
while (reading statement succeeds) { // ... }
In the case of reading character by character (which perhaps you should reconsider), it looks like this:
while ( (currentChar = fgetc(file)) != EOF) { // ... }
#9 Members - Reputation: 141
Posted 07 October 2012 - 11:32 AM
The problem was that I had an extra delimiter at the end of the file. Thanks guys.
#10 Crossbones+ - Reputation: 18775
Posted 07 October 2012 - 12:16 PM
Well, you also had fragile code that couldn't detect that mistake in the file. Proper error handling is tedious and hard to learn, but it's very important, so you should take this opportunity to practice by making your code detect anything that could be wrong with the file.