Hello,
I have been writing a piece of code to pull a set of numbers out of a text file and store them in assorted int and double variables and int and double arrays. Currently my program does this and successfully stores all the values, however it returns a large memory error and prints out a ton of memory locations when it is finished. I have isolated the problem to the following 2 lines of code:

cwint[i] = atol(tempString.c_str());   //convert string to integer value and store in cwint int array 

    prior[i] = strtod(tempString.c_str(),NULL); // convert string to double and store in prior double array

These lines work as intended in other places in the code, however I have isolated it to these 2 lines, as if they are commented out the program runs without any errors. I have also tried using the copy() function of the string class to copy these to a character array and that caused the same error.

The code in its entirety can be seen here: the error lines are line 96 and line 92

/************************************************************************
FileReaderTest3.cpp
Created by -----------------------
2008.6.18
Reads in the numbers from Hamming74stats6v1ivarp2corrp9.txt and converts
them to appropriate variables for use in Matlab to C++ conversion
*************************************************************************/
	#include <iostream>
	#include <fstream>
	#include <string>
	#include <sstream>
	
	using namespace std;

//global variables
int Bits, N, startTrials;
double probeInfoMean, probeInfoVar,probeCovarVal, probeNoiseVar;
char line[256];
string tempString;
stringstream lineSStream;

//--------------------------------------------------------------------------- 
//Gets the parameters from the first line of the file as well as the number
//of lines of probability information to read
//---------------------------------------------------------------------------
int getParameters(ifstream * inputFile)

{
//Only do the majority of this program if the file is open


//Read in first line of text, pass #s to assorted variables
//format: # # ####### ##.#### #.#### #.#### #.####
       inputFile->getline(line, 256);
       lineSStream << line;

	
	
	for(int i=1;i<8;i++)
	  {
            getline(lineSStream, tempString, ' ');
       
            switch(i)
              {
                case 1  : Bits=atoi(tempString.c_str());			break;
                case 2  : N=atoi(tempString.c_str());				break;
                case 3  : startTrials=atoi(tempString.c_str());			break;
                case 4  : probeInfoMean = strtod(tempString.c_str(),NULL);	break;
                case 5  : probeInfoVar = strtod(tempString.c_str(),NULL);	break;
                case 6  : probeCovarVal = strtod(tempString.c_str(),NULL);	break;
                case 7  : probeNoiseVar = strtod(tempString.c_str(),NULL);	break;
                default : cout << "For 1-7 seems to have decided to go outside the bounds of 1-7, that sucks";
              }
          }	
	cout <<"Parameters: "<< Bits<<" " << N<< " "<< startTrials<<" "<< probeInfoMean<<" "<< probeInfoVar<<" "<<probeCovarVal<<" "<< probeNoiseVar<<'\n';
	return 0;
}

//--------------------------------------------------------------------------- 
//codeword and probability information
//--------------------------------------------------------------------------- 
int getProbability(ifstream * inputFile)
{


//read in 2nd line
//format: ####
        int nzcwint;
        inputFile->getline(line, 256);
        nzcwint = atoi(line);
	
	cout<<"Lines to get: "<< nzcwint << '\n';// test output	
        cout << "Data: \n"; // test output

//Read in 3rd-Last lines of text file
//format: #############.#  #.######### 

        //initialize variables, use pointers so I can have a array of variable length
        long * cwint;
        double * prior;
	prior = (double*) malloc(nzcwint); //allocate memory for array
	cwint = (long*) malloc(nzcwint); //allocate memory for array
        	
        for(int i=0;i<nzcwint;i++)
          {

            lineSStream.clear();
            inputFile->getline(line, 256); //read in entire line
            lineSStream << line; //pass line to stringstream

            getline(lineSStream, tempString, ' '); //create String of character up to first space
            cwint[i] = atol(tempString.c_str());   //convert string to integer value and store in cwint int array THIS LINE CAUSES PROGRAM CRASHES

            getline(lineSStream, tempString, ' '); //get null space inbetween integers
			getline(lineSStream, tempString, ' '); //create string of characters after first whitespace until end of line
			prior[i] = strtod(tempString.c_str(),NULL); // convert string to double and store in prior double array THIS LINE CAUSES PROGRAM CRASHES
		

            cout << "line: " << i+1 << "	prior: " << prior[i] << "    	cwint: " << cwint[i] <<'\n'; // test output
          }

	free(prior); //free allocated memory
	free(cwint); // free allocated memory
	return 0;

}


//---------------------------------------------------------------------------
int main(int argc, char *argv[])
  {

   if(argc==2)
   {

          //open file entered by user
          ifstream inputFile;
          inputFile.open(argv[1]);

          if(inputFile.is_open())
            {
               getParameters(&inputFile);
               getProbability(&inputFile);
            }
    
           else cout << "Error opening file" << '\n'; //error if the file did not open which also caused most of that other stuff to not go
    
           inputFile.close(); //close file

   }	
   else cout << "You either have too many or no files as parameters. " << '\n'; // 


    return 0;

}

These pull text from a file in the format:

7 6 5000000 10.000000 0.200000 0.900000 0.000000
253
2458750411719.0 0.000055400
2458750411724.0 0.000010800
2458750412359.0 0.000009000
2458750412364.0 0.000005800
2458750493639.0 0.000009000
2458750493644.0 0.000006200
2458750494279.0 0.000004000
2458750494284.0 0.000008600
2458760897479.0 0.000008400
2458760897484.0 0.000006000
2458760898119.0 0.000003400
...


The Error thrown when the program is ran is:
*** glibc detected *** ./FileReader: double free or corruption (!prev): 0x0804d3e0 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7d1aa85]
/lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7d1e4f0]
./FileReader[0x80494bf]
./FileReader[0x8049569]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7cc5450]
./FileReader(__gxx_personality_v0+0x55)[0x8048d71]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 08:05 18337 /media/Stuff/ECC_Job/temp/FileReader
0804a000-0804b000 rw-p 00001000 08:05 18337 /media/Stuff/ECC_Job/temp/FileReader
0804b000-0806c000 rw-p 0804b000 00:00 0 [heap]
b7b00000-b7b21000 rw-p b7b00000 00:00 0
b7b21000-b7c00000 ---p b7b21000 00:00 0
b7cae000-b7caf000 rw-p b7cae000 00:00 0
b7caf000-b7df8000 r-xp 00000000 08:06 393018 /lib/tls/i686/cmov/libc-2.7.so
b7df8000-b7df9000 r--p 00149000 08:06 393018 /lib/tls/i686/cmov/libc-2.7.so
b7df9000-b7dfb000 rw-p 0014a000 08:06 393018 /lib/tls/i686/cmov/libc-2.7.so
b7dfb000-b7dfe000 rw-p b7dfb000 00:00 0
b7dfe000-b7e08000 r-xp 00000000 08:06 375424 /lib/libgcc_s.so.1
b7e08000-b7e09000 rw-p 0000a000 08:06 375424 /lib/libgcc_s.so.1
b7e09000-b7e0a000 rw-p b7e09000 00:00 0
b7e0a000-b7e2d000 r-xp 00000000 08:06 393026 /lib/tls/i686/cmov/libm-2.7.so
b7e2d000-b7e2f000 rw-p 00023000 08:06 393026 /lib/tls/i686/cmov/libm-2.7.so
b7e2f000-b7f17000 r-xp 00000000 08:06 369306 /usr/lib/libstdc++.so.6.0.9
b7f17000-b7f1a000 r--p 000e8000 08:06 369306 /usr/lib/libstdc++.so.6.0.9
b7f1a000-b7f1c000 rw-p 000eb000 08:06 369306 /usr/lib/libstdc++.so.6.0.9
b7f1c000-b7f22000 rw-p b7f1c000 00:00 0
b7f2e000-b7f31000 rw-p b7f2e000 00:00 0
b7f31000-b7f32000 r-xp b7f31000 00:00 0 [vdso]
b7f32000-b7f4c000 r-xp 00000000 08:06 375379 /lib/ld-2.7.so
b7f4c000-b7f4e000 rw-p 00019000 08:06 375379 /lib/ld-2.7.so
bf960000-bf975000 rw-p bffeb000 00:00 0 [stack]
Aborted

Thank you
Greyspectre


(and yes I know the numbers in the file are to big to be stored as ints or longs)

Member Avatar for iamthwee

Seeing as this is c++ why not use and stick with c++ functions?

You are not allocating enough storage, change from

prior = (double*) malloc(nzcwint);

to

prior = (double*) malloc(nzcwint * sizeof(double));

// + allocation of cwint in same fashion ...

Then again, why aren't you using new/delete, i.e.

prior = new double[nzcwint];
// etc
// and eventually ...
delete [] prior;

Then about conversions, stringstream is capable of doing the conversions you need. Consider ...

string test = "12301230 786345.94";
    long i;
    double d;
    stringstream sstrm;

    sstrm << test;

    if(sstrm >> i >> d)
    {
        cout << "i: " << i << "\nd: " << fixed << d;
    }
    else
    {
        cout << "Conversion error";
    }

Much appreciated, I am still working on fully grasping pointers as this is my first c/c++ program I have written

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.