Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Pointers...

Status
Not open for further replies.

hne

Programmer
Oct 16, 2003
38
US
Hello gurus,
I have a code I inherited that is loaded with pointers. Here is my problem. The application is reading a stream file to get the data. There is a delimiter 'xle' or 'xlc' or 'eof' that let the app know when it is at the end of a block. The app uses a 'get(char*, n, c)' function to get the data. However, when the app tries to determine the 'strlen' or 'strcmp' the pointer. I get an Access Violation'. Example below. Please help. Thx.

char IVectrfile::getField(char **saveaddr = NULL)
{
long curloc = tellg();
int n = 0;
bool done = false;
char c;
char *dat;
while ( !done )
{
c = ifstream::get();
if((c == '\x1c') || (c == '\x1d') || (c == '\x1e') || (c == EOF))
done = true;
n++; // count will include the terminator
}
if (n > 1) // data other than the terminator
{
seekg(curloc);
dat = new char[n];
//copy the field to the memory up to the trmator
get(dat, n, c); // end the field with \0
ifstream::get(); // get rid of the terminator
// put the address into saveaddr
*saveaddr = dat;
}
}
...
...
char ** flds = 0;
if (pTf->WantThisData(flds))
{
// if 'all passengers' add it to the pnr ssrlist
// else find the passenger(s) and add it to them
findAndAddData(flds);
}
clear(flds);
...
...
int WantThisData(char ** ssrInfo)
{
/***************************************************
The application fails on the 'if' statement below
***************************************************/
// esrDataNo is a 'typedef enum' value is 6
if ((strlen(ssrInfo[esrDataNo]) > 0)
&& (strcmp(fltno, ssrInfo[esrDataNo])))
return 0;

return 1;
}
 
Of course, it was not the best idea to inherit IVectfile from std::ifstream, but one of possible problem causes is here:
Code:
   char ** flds = 0;
   if (pTf->WantThisData(flds))
...
int WantThisData(char ** ssrInfo)
{
   /***************************************************
    The application fails on the 'if' statement below
   ***************************************************/
   // esrDataNo is a 'typedef enum' value is 6
   if ((strlen(ssrInfo[esrDataNo]) > 0)
      && (strcmp(fltno, ssrInfo[esrDataNo])))
It's obviously the program tries to get a string address via null pointer...
I don't know why WantThisData called as a member function (via pTf pointer) but no class prefix in its definition presented. May be you extract the definition from a class declaration...

Regrettably, it's not the only defect of this snippet. For example:
1. It's a wrong way to test C++ istream eof condition:
Code:
char c;
...
c = ifstream::get(); // what's a dirty trick...
if(... || (c == EOF))
Never mix C and C++ stream stuff! The EOF is the C library macros with int type value (as usually -1). Now the program compares char and int values. If a C++ compiler treats char type as unsigned (it's conforming with C++ Standard implementation), c is NEVER equal to EOF!

In actual fact istream::get() returns char_traits<char>::int_type type value and the eof condidition signalled with char_traits<char>::eof() value. That's why better use get(c) member function: it returns istream& and it's easy to detect not only eof but fail consition too (see below).

Moreover: no any special EOF char in the stream. You can't skip or ungetc this phantom after eof condition.

The right and portable method (one of) in that case:
Code:
if (!ifstream::get(c))
{
   // eof or i/o error... break the loop...
}
else // now chech for other real delimiters...
...
Now Coup de Grace:
After end-of-file you (or your predecessor) can't do any stream ops until clear the stream. So seekg and the last gets do nothing in that case - no data in dat buf at all!
You must clear the stream state with clear() member function.

Apropos, why ifstream::get() but simply seekg(x) and get(x,y,z) used in this unprepossessing ifstream bastard?

I hope, you can make proper corrections of this strange code...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top