Link to home
Start Free TrialLog in
Avatar of letharion
letharionFlag for Sweden

asked on

Same code on Windows and Linux, different results

I'm writing a windows dll, but doing some testing of the same code on a linux box.
My function works perfectly on the linux box. Then I copy paste it into Visual Studio, and I copy the datafile that the function works on.

On linux, the code loops over each line of my file, and inputs the data into a vector.
The number of datarows in the vector is 3081, as is the number of lines in my file. Makes sense.

However, when compiled as a dll and executed under windows however, I get to datarows in my vector, for each line in my datafile.

Expected output from both functions would be
3081
3081

Linux/GCC 3.4.6 output is
3081
3081

Windows/Visual Studio/Discipulus(the app that calls my dll) output is:
3081
6162 (aka 3081 * 2)

I'm attaching the code below, hoping that someone can see wtf is going on.
Or tell me that vectors work differently on Windows than on Linux, or something similar, so I can figure this out. I've programmed a lot, but I'm somewhat new to C++
//Code on windows, Visual Studio Pro 2008
ifstream myfile ("c:\\training.txt", ios::in);
if (myfile.is_open()) {
	int counter = 0;
	int params = 0;
	string line;
	while (!myfile.eof()) {
		getline (myfile,line);
		if(line.length() == 0) break;
		vector<string> dataRow;
		params = explode(line, "    ", dataRow);
			for(int i = 0; i < NR_OF_INPUTS; i++) {
			logfile << i << endl;
			inputVector[i].push_back(StrToF(dataRow[i]));
		}
		
		counter++;
	}
	myfile.close();
	logfile << counter << endl;
	logfile << inputVector[0].size() << endl;
}
 
//Code on linux. Vim + GCC 3.4.6
ifstream myfile ("training.txt", ios::in);
if (myfile.is_open()) {
   int counter = 0;
   int params = 0;
   string line;
   while (!myfile.eof()) {
      getline (myfile,line);
      if(line.length() == 0) break;
      vector<string> dataRow;
      params = explode(line, "    ", dataRow);
       if(dataRow.size() != NR_OF_INPUTS) cout << "fel" << endl;
       for(int i = 0; i < NR_OF_INPUTS; i++) {
         logfile << i << endl;
          inputVector[i].push_back(StrToF(dataRow[i]));
       }
        counter++;
   }
   myfile.close();
   cout << counter << endl;
   cout << inputVector[0].size() << endl;
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Infinity08
Infinity08
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi letharion,

I can see no problem with the code ...

Are you sure the 'inputVector[0]' is empty before the loop? How is 'inputVector' declared?

ZOPPO
You read from a textfile. You should know that at windows each line is ended by a pair of CRLF (carriage-return/linefeed) while at linux it is a single linefeed only. So, you need to create the textfile separately for each platform.

I also wonder your outputs. Why did you only print the inputVector[0].size and not other vectors as well?

>>>> I get two datarows in my vector

The most reasonable cause for the different results is the following line:

    if(line.length() == 0) break;

If the line read has zero length at Linux it would break. If it is a non-empty line - e. g. because of some wrong linefeed terminator or spaces - the break wasn't done and the loop with push_back was done again.
>>>> while (!myfile.eof()) {
>>>>            getline (myfile,line);

You better do

  while (getline (myfile,line)) {

what stops for both EOF and bad reads.
You did not explain where NR_OF_INPUTS comes from. If for any reason it happens to be 2 on Windows, 1 on Linux - that would explain your results.
IMMO there can't be anything wrong with the file reading part and the 'if(...)break'. Since in both cases counter is equal in both cases the difference must be in the inner loop ...
>>>> IMMO there can't be anything wrong with the file reading part and the 'if(...)break'.
You are right (though these parts should be revised nevertheless).

The reason for doubling the sizes is either

(A) inputVector[0] isn't empty at beginning but contains already 3081 entries in the windows version (ZOPPO)
(B) the StrToF(dataRow[i]) returns an array of 2 and not a single value.

The NR_OF_INPUTS is irrelevant as the output was inputVector[0]. So it doesn't matter whether inputVector[1] was filled or not.

I would guess that ZOPPO was right with (A) and the inputVector wasn't empty but filled a second time in the above loop.

Anyway, StrToF is not a standard function; on unix, there is a standard strtof {http://linux.die.net/man/3/strtof} that returns a (single) float. Therefore it is possible that the windows implementation has a bug.
Avatar of letharion

ASKER

As it turns out, inputVector is indeed not empty before the loop. It's automagically filled somewhere, gonna try figuring out where/why that happens during dll call but not otherwise. Thanks for all of your input :)
(Btw, I thought it fair to accept Infinity08s solution, but if you disagree for some reason, just let me know)