Link to home
Start Free TrialLog in
Avatar of samj
samj

asked on

ofstream seg fault

Hi

I am getting a seg fault, only if I replace the "(*m_os[*i])" with
"cout" it prints. how can I fix this?

many thanks

class A
{
    std::map<std::string, std::ofstream*> m_os;
    std::map<std::string, myType> t4s;
    std::vector<string> file_names;
public:
    A(){}
    void A_Mthd();
};

A::A()
{
   void populate();
}

void A::populate()
{
  /* some code to fill file_names vector here */

  /* Populate the ostream pointers map. */
  for( vector<string>::iterator i = file_names.begin(); i != file_names.end(); i++ )
      {
        string f = "mydirectory/" + (*i);
        ofstream* p_of = new ofstream( f.c_str(), ios::app);
        m_os[*i] = p_of;
      }


void A::A_Mthd(){
 for( vector<string>::iterator i = file_names.begin(); i != file_names.end(); i++ )
   (*m_os[*i]) << t4s[*i].B_Mthd() << " " << endl;
}
Avatar of samj
samj

ASKER

the exampel above given as a representation of the part of a larger code which exebits the problem. thanks
Avatar of samj

ASKER

please note a correction,
in the A::A ctor, the line
void populate();
is actually
populate();
Avatar of Infinity08
It might be a copy-paste problem, but this method's implementation does not have a closing }

    void A::populate()
    {
      /* some code to fill file_names vector here */

      /* Populate the ostream pointers map. */
      for( vector<string>::iterator i = file_names.begin(); i != file_names.end(); i++ )
          {
            string f = "mydirectory/" + (*i);
            ofstream* p_of = new ofstream( f.c_str(), ios::app);
            m_os[*i] = p_of;
          }

And it's not defined in your class :

    class A
    {
        std::map<std::string, std::ofstream*> m_os;
        std::map<std::string, myType> t4s;
        std::vector<string> file_names;
    public:
        A(){}
        void A_Mthd();
    };

And finally, you redefined the constructor. It was already defined here :

        A(){}

(and of course the mistake you already posted).

These might all be copy-paste errors, but it's worth trying them anyway.


Now, with all the mistakes fixed, I ran this code and it worked (note that I didn't use the t4s map because I don't know its implementation) :

#include <iostream>
#include <fstream>
#include <vector>
#include <map>
#include <string>

using namespace std;

class A
{
    std::map<std::string, std::ofstream*> m_os;
    //std::map<std::string, myType> t4s;
    std::vector<string> file_names;
public:
    A();
    void A_Mthd();
    void populate();
};

A::A()
{
   file_names.push_back("bla.txt");
   populate();
}

void A::populate()
{
  /* some code to fill file_names vector here */

  /* Populate the ostream pointers map. */
  for( vector<string>::iterator i = file_names.begin(); i != file_names.end(); i++ )
      {
        string f = "mydir/" + (*i);
        ofstream* p_of = new ofstream( f.c_str(), ios::app);
        m_os[*i] = p_of;
      }
}

void A::A_Mthd(){
 for( vector<string>::iterator i = file_names.begin(); i != file_names.end(); i++ )
   (*m_os[*i]) << "test" << endl;
}

int main(void) {
  A a;
  a.A_Mthd();
  system("PAUSE");
  return 0;
}
Try the above code, rebuild completely, and watch the result ...

For your code, just try a "rebuild all" or similar to make sure that every object file is re-generated.
Avatar of samj

ASKER

infinity08:
yes, the typos are as a results of comming up with some representation to the real code without compiling it before posting, just to present the ideas, however the "problem part" of the code I have works the way it originally is when placed in a different project, which tells me that the real problem withe the seg fault is somewhere else and not in the code posted, since it compiled with no errors.
I will have to look into it more and post again if the problem still there, for now, if you have no objection, I would like to paq this thread.
If you prefer ...

To find the exact location of the segmentation fault, just step through your code using a debugger, or add debugging output to narrow down the line of code that generates the seg fault.

If you found that line, then post that line here as well as the code directly around it and related to it.

I'll be happy to help you find the problem ...
>  (*m_os[*i]) << t4s[*i].B_Mthd() << " " << endl;

You substituted (*m_os[*i]) with cout and it survived, which suggests that the problem in in the m_os map. I'd sanity-check the pointers that were put into the map and sanity-check the ones coming out of it. A NULL pointer would cause a SIGSEGV. Have you checked that the pointer is non-NULL?
Avatar of samj

ASKER

infinity08:
the exact line is as mensioned by rstaveley.

rstaveley:
how can I check for the NULL pointer?
I changed the line to
cout << (*m_os[*i]) << endl;
but still gives the seg fault.
I can't use a debugger because it is a threaded code and when I tried to use gdb, it gave me all kind of truble.

I tried
cout << m_os[*i] << endl;
and it printed "0", that is zeros in evey line. hummm is this a NULL pointer? and if so, what then?

I went to the part of the code where the m_os gets populated and did
cout << p_of << endl;  //"please note the OP section with stating comment /* Populate the ostream pointers map. */"

and printed:
 0x82d6a10
0x82d9448
0x82d96c8
0x82d6c90
0x82d6f10
0x82d7190
0x82d7430
0x82d76d0
0x82d7970
0x82d7c10
0x82d7eb0
0x82d8150
0x82d83f0
0x82d8690
0x82daf60
0x82db200
0x82db4a0
0x82db740
0x82db9e0
0x82dbc80
0x82dbf20
0x82dc1c0
0x82dc460
0x82dc700
0x82dc9a0
0x831e590
0x8320818
0x8322aa0
0x8324d28
0x8326fb0
0x8329258
0x832b500

so, some where in the memory registery, it is loosing it? that is very strange
thanks

>> I tried
>> cout << m_os[*i] << endl;
>> and it printed "0", that is zeros in evey line. hummm is this a NULL pointer? and if so, what then?
Yes, that's a NULL pointer, and that's the cause of the segmentation fault.

You said this was threaded code. Does every thread have its own copy of this A object ?
What happens between calling the constructor of the A object, and the A_Mthd call ?
Avatar of samj

ASKER

the treaded part is very early on and has nothing to do with the trubled part of the code. it is just mensioned to give the reason whey the gdb may have not liked and gave me so much truble using it.

>>What happens between calling the constructor of the A object,
please notice the output in my last post. it seams to run fine and populate the map.

>>and the A_Mthd call ?
well, that is where the problem happens.

am I miss understanding your question?
>> am I miss understanding your question?
I think so. The test code :

    A a;
    A.A_Mthd();

runs fine, so there has to be something else between those lines of code. What happens then ? Can you show some more code ? ie. the whole class, and the code between construction of the A object and the call to the A_Mthd() method that causes the seg fault.
SOLUTION
Avatar of rstaveley
rstaveley
Flag of United Kingdom of Great Britain and Northern Ireland 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
Avatar of samj

ASKER

over the week end, I rebooted the computer, started the code, and it worked fine without the seg fault. strange, really strange. I have a very good memory, kingstone, the correct one for the MB, I don't know what to say.
Did you modify anything before restarting ? Did you re-compile (parts of) the code ?
Avatar of samj

ASKER

not at all, I did not modify any thing at all. nor did I re_compile it. however, during the time the problem was there, I did few make clean; make just to make sure that it builds every thing a new, and that did not fix it. I am suspecting the OS being Fedora Core 5 which is a test bed for Red Hat, buggy as ****.  donotno...
Are you using any dynamic libraries for this code, or is everything statically compiled into one executable ? Does it depend on other binaries ?
Avatar of samj

ASKER

it depends on other binaries, boost is one of them and there is another propritory lib.
Might have been a link issue, so that incompatible code was loaded in memory. I can't be sure though. If you say it's fixed now, and it stays that way, then I guess the problem is solved :)
Problems that inexplicably go away in your development environment have a nasty habit of biting you later in production. I recommend you invest some time trying to reproduce the problem. [Speaks a bitter voice of experience :-)]
Avatar of samj

ASKER

finding the real problem wouild be interesting indead, actuall as I am typing this, it showed up again but with a different part of the code, again, seg fault. yes, I have a static and anohter dynamic libs being linked to this proj, I mean one is libxxx.a and the other being boost "dynamic" since its name ends with .so on my system, I don't know what steps to take to venture into this. I have not restarted the PC yet. any suggestions.
ASKER CERTIFIED SOLUTION
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
Avatar of samj

ASKER

well, this time is not with a pointer being dereferenced. it is as a result of indexing an empty vector but that happened becasue ifstream did not open the file it was given as an arg.
using gdb, I printed the arg "file name" toke it "copied" to the command line and was able to cat the same exact link "cat /path/to/file" and its privilates are -rw-r--r-- it is just a text file of data. but when checked with is_open() on the stream, it retruned false.
ifstream ifs(filename.c_str());
not sure if this is related to the other problem or not.
>> it is as a result of indexing an empty vector
That uses pointers internally, so it's similar.

>> but when checked with is_open() on the stream, it retruned false.
That means there was a problem opening the file, or it has been closed already. Where do you do the is_open() and where do you open the file for reading ?
If you are opening lots of files, you might want to check that you are not hitting ulimit -n (max files open). Usually it is 1024 in a bash shell for a user.
Avatar of samj

ASKER

string f = str_var1 + str_var2;
ifstream ifs( f.c_str() );
if( ifs.is_open() )
 cout << "is open" << endl;
else
 cout << "closed" << endl;

very staright forward.
I would indeed be thinking towards rstaveley's idea ... how many files does your program open ?
Avatar of samj

ASKER

how can I check, well, I did not open 1024 files for sure, not even 50, there are minimum 33 open now, is there a shell command that tell me how many are open right now?
Avatar of samj

ASKER

I have a code running with about 35 files open. the code I am trying to run "the one with the problems" will open a few, but the time it opens said file "file not being open" it probably open 10 or so, so I don't see a problem since ulimit -n reported 1024 on my system.
Avatar of samj

ASKER

I even closed the other running code down, and still having the same problem, not opening the file, I can reboot but I want to get my fingers on the problem.
Ok, so the file exists and it's not currently used by another application, correct ?

And then you do this :

    ifstream ifs( f.c_str() );
    if( ifs.is_open() )
     cout << "is open" << endl;
    else
     cout << "closed" << endl;

and it prints "closed" ... correct ? And f.c_str() does return the correct filename ?
You might want to use lsof to see how many open files you have.

e.g. If your username is samj

  lsof | grep samj | wc -l

It is possible that your open files are because of some other process in your shell. These would certainly clear up after a reboot.
Also check that you always close a file when you don't need it any more ...
Yes, the problem with using a pointer to fstream is that it doesn't automatically close when it goes out of scope.
Having said that, it would close when you stopped the application.
Well, I've got the impression (correct me if I'm wrong) that this application runs all the time ...

Just to understand better : what does the application do with the files ?
Avatar of samj

ASKER

Infinity08;
in answering both of the questions posted,
yes.
yes.
also;
yes, the app. runs all the time. it connects to Big Bucks Inc, using their api and shares info back and forth, retreving data, processing data, send/receive info and instructions. thus some files have to be open all the time. others don't.

the file I am trying to open and thus have been giving the truble, has nothing to do with it, it is a file I just made up with the touch command to check on this problem after failing to open the file intended for to be open, just to make sure it is not being open with another instance of the applicaion.

lsof | grep samj | wc -l
reports
551
wow, never dreamed so many are opon at one time.
Avatar of samj

ASKER

I rebooted.
the seg fault went away, I will have to go through my code and appy the recommendations you both said.
1) close file when not in use.
2) if( !ptr ) Throw else de-ref and go on.

but for now, how is it that it did not even open a new file I just made up.
Avatar of samj

ASKER

after booting, I run nothing execpt the code with the problem "not openig the file" it still reported "closed", yes, there is not seg fault, so I am going to back check and apply the close recommendation and report back.
Avatar of samj

ASKER

#include <sstream>
#include <istream>
#include <string>

using namespace std;

int main(){
  string f_name = "../myProg/str1/some_file";
  ifstream ifs(f_name.c_str());
  if( ifs.is_open() )
    cout << "is open" << endl;
  else
    cout << "closed" << endl;
}
******************************************************************
~/toy $ make clean; make
rm -rf *.o proj
g++ -gdwarf-2   -c -o my.o my.cpp
my.cpp: In function ‘int main()’:
my.cpp:9: error: variable ‘std::ifstream ifs’ has initializer but incomplete type
my.cpp:11: error: ‘cout’ was not declared in this scope
my.cpp:13: error: ‘cout’ was not declared in this scope
make: *** [my.o] Error 1
#include <fstream>
Avatar of samj

ASKER

to fix it, I had to use.
#include <fstream>
#include <ios>
#include <iostream>
ifstream ifs(f_name.c_str(), ios::in);
which reported open,

but when used the same setup with the original code, it reported closed.
Avatar of samj

ASKER

does the following statement open the file, thus I need to close it once done?

ofstream* fily = new ofstream( f_name.c_str(), ios::app);

Avatar of samj

ASKER

here is as fare as I can get to the real code.



#include <fstream>
#include <ios>
#include <iostream>
#include <string>
#include <vector>
#include <map>

#include <boost/tokenizer.hpp>
#include <boost/lexical_cast.hpp>
#include "dat_col.h"
#include "xxxx.h"
#include "useful.h"

using std::map;
using std::string;
using std::vector;
using std::cout;
using std::endl;
using std::flush;
using std::stringstream;
using std::ifstream;
using std::ofstream;
using std::ios;
using BBI::xtty;
using BBI::xppy;
using BBI::OAException;

Retrever::Retrever(Info* inf, string f_name, time_t st):
...
{
  fill_up();
}

void Retrever::fill_up()
{
...
  string f = f_name;
  std::ifstream ifs( f_name.c_str(), ios::in );
  int lot_start = start_time + lot_sz * 60 * 60 * (lot_no - 1);      // include the start_here
  int lot_end = start_time + lot_sz * 60 * 60 * lot_no;              // exclude the end
  string line;
  if( ifs.is_open() )
    cout << "is open" << endl;
  else
    cout << "closed" << endl;
}


class Dat_Col
{
  time_t tmp;
  map<string,Retrever*> m_retrevers;
  vector<stirng> _unique;
  void make_unique();
public:
  Dat_Col(Info*);
};

Dat_col::Dat_col(Info* info):
  info(info)
{
  make_unique();
}

void Dat_col::make_unique()
{
  string f = file_name;
  ifstream ifs( f.c_str() );
  string line;
  getline( ifs, line );
  stringstream ss( line );
  time_t tmp = 0;
  ss >> tmp;
  ...;
  ifs.close();

  for( vector<string>::iterator i = _unique.begin(); i != _unique.end(); i++ )
    {
      Retrever* p_rtv = new Retrever(info, *i, tmp);
      m_retrevers[*i] = p_rtv;      
    }
}
Avatar of samj

ASKER

ok, a new bit of info.

using
  std::ifstream ifs( f_name.c_str(), ios::in );
  cout << ifs.fail() << cout;

prints 1

so it is a .
ohh *******.
my stupidity.
std::ifstream ifs( f_name.c_str(), ios::in );
should be
std::ifstream ifs( f.c_str(), ios::in );
Avatar of samj

ASKER

thank youi
>> std::ifstream ifs( f_name.c_str(), ios::in );
>> should be
>> std::ifstream ifs( f.c_str(), ios::in );
:) Sometimes you can be so close to the problem that you miss the obvious ...

So, is it fixed now ?
Avatar of samj

ASKER

well, the seg fault, I don't know  yet, it is a tricky one, I have to fix some programming behaviour first, so I went back and cleaned the namespace by using :: operator instead of just opening it all up, specially when I have 2 libs, 2 of which have their own namespace, and my own lib, 3 in total.

in addition to the recommendations you guys put forward.

thank you :)
Keep us informed :)