Segmentation Fault in fclose()...why?

Discussion in 'C++' started by VB, Jan 12, 2005.

  1. VB

    VB Guest

    Hi,

    here File.cpp and File.h:


    File.cpp:

    ----------------------
    #pragma warning (disable: 4786)

    #include <cstring>
    #include <cstdlib>
    #include <cassert>
    #include "File.h"

    //////////////////////////////////////////////////////////////////////
    // Construction/Destruction
    //////////////////////////////////////////////////////////////////////

    File::File(const char* filename, bool ld)
    {
    fn_in = new char[strlen(filename)+1];
    std::strcpy(fn_in,filename);

    load = ld;
    maxcnt = isetsz = 0;
    curr = reccnt = 0;
    // bufsid = -1;
    }

    File::~File()
    {
    if (file)
    std::fclose(file);
    if (fn_in)
    delete[] fn_in;
    }

    bool File::read(ITEMSET& s)
    {
    if (curr == isetsz) { /* if all records read */
    curr = 0; /* reset position of current pointer */
    if (!load) /* if to work on input file */
    if(!std::fseek(file, pos, SEEK_SET))
    error(E_FREAD,fn_in); /* reset file position */
    return false; /* return no file read */
    }

    if (load) /* if to work on memory */
    cis = isets[curr]; /* get current itemset */
    else
    get_iset(); /* otherwhise read from file */
    curr++; /* and increment the counter */

    s = cis; /* return s */
    return true;
    }


    ITEMSET* File::read()
    {
    if (curr == isetsz) { /* if all records read */
    curr = 0; /* reset position of current pointer */
    if (!load) /* if to work on input file */
    if(std::fseek(file, pos, SEEK_SET) != 0)
    error(E_FREAD,fn_in); /* reset file position */
    return NULL; /* return no file read */
    }

    if (load) /* if to work on memory */
    cis = isets[curr]; /* get current itemset */
    else {
    get_iset(); /* otherwhise read from file */
    cis.prepare(); /* sort and remove duplicates */
    }
    curr++; /* and increment the counter */

    return &cis; /* return s */

    }


    int File::reorg(long thresh)
    {
    SymTab tmap; /* temporary symbol table */
    int i, size;
    ITEM* item;
    std::vector<ITEM*> sorted = nimap.bvec; /* bucket vector */
    std::sort(sorted.begin(),sorted.end(),frqcmp()); /* order by
    frequency */

    for (i = 0, size = sorted.size();
    (i < size) && (sorted->frq >= thresh); i++)
    {
    item = (ITEM*)tmap.insert(nimap.ids[sorted->id], sizeof(ITEM));
    if (!item)
    return E_NOMEM; /* add the new item to the map, */
    item->frq = sorted->frq;
    }
    nimap = tmap;

    return 0;
    }

    int File::reset()
    { /* resets to the beginning */
    if (load) /* if to work on memory */
    curr = 0; /* set the current pointer to 0 */
    else {
    if(std::fseek(file, pos, SEEK_SET) != 0) /* otherwise reset the file
    pointer
    */
    error(E_FREAD,fn_in); /* checking for I/O errors */
    }
    return 0; /* return OK */
    }

    ITEMSET* File::read(long i)
    { /* read i-th record */
    if (i < isetsz) { /* if current record exist */
    if (!load){ /* if to work on input file */
    int locpos = ftell(file); /* get the local record position */
    if(std::fseek(file, pos, SEEK_SET) != 0) /* set the file pointer
    */
    error(E_FREAD,fn_in); /* checking for I/O errors */
    long cnt = 0; /* get the local record counter */
    while(read()&&(++pos<i)); /* read records in sequence until ith */
    if(fseek(file, locpos, SEEK_SET) != 0) /* reset the file pointer
    */
    error(E_FREAD,fn_in); /* checking for I/O errors */
    }
    else cis = isets;
    return &cis; /* return s */
    }
    else return NULL; /* return no file read */
    }

    bool File::load_iset(int i, ITEMSET &trans)
    {
    if (i < isetsz) { /* if current record exist */
    if (!load){ /* if to work on input file */
    int locpos = ftell(file); /* get the local record position */
    if(std::fseek(file, pos, SEEK_SET) != 0) /* set the file pointer */
    error(E_FREAD,fn_in); /* checking for I/O errors */
    long cnt = 0; /* get the local record counter */
    while(read()&&(++pos<i)); /* read records in sequence until ith */
    if(std::fseek(file, locpos, SEEK_SET) != 0) /* reset the file
    pointer */
    error(E_FREAD,fn_in); /* checking for I/O errors */
    } else
    trans = isets;

    return true; /* return s */

    } else
    return false; /* return no file read */

    trans=isets;
    }

    char* File::readTrans(int trans)
    {
    int l = 0;
    int i;
    for (i = 0; i < isets[trans].size(); i++) {
    l += std::strlen(lookup(isets[trans]->id)) + 1;
    }
    char* result = new char[l + 1];
    strcpy(result,"");
    for (i = 0; i < isets[trans].size(); i++) {
    std::strcat(result,lookup(isets[trans]->id));
    std::strcat(result," ");
    }

    //fn_in = new char[strlen(filename)+1];
    //strcpy(fn_in,filename);
    return result;
    }




    ----------------------

    Here file.h:

    ------------------------------------

    #ifndef FILE_HPP_INCLUDED
    #define FILE_HPP_INCLUDED

    #include <vector>
    #include "resources.h"
    #include "Ctfscan.h"
    #include "SymTab.h"

    #define BUFSIZE 256 /* size of read buffer */

    class File
    {
    public:
    char* readTrans(int trans);

    ITEMSET* read(long i);
    int reset();
    bool loaded() const;
    int items();

    hash_map<int, int> classcount;
    hash_map<std::string, int, hashString, eqstr> classes; /*
    Transaction-class
    mapping */
    ITEMSET* read();
    SymTab& symbols();
    void insert_iset(ITEMSET is){isets.push_back(is);};
    bool load_iset(int i, ITEMSET &trans);
    const char* lookup(int id) const;
    const char* looktr(int id) const;
    int reorg(long thresh);
    int size() const;
    bool read(ITEMSET& s); /* read an itemset from buffer */
    File(const char* fname, /* file name */
    bool load = true /* flag for loading item sets */
    );
    virtual ~File();
    protected:
    FILE* file; /* file pointer */
    SymTab nimap; /* name/identifier map */
    SymTab trmap; /* Transaction map */
    private:
    virtual void read_blk() = 0; /* caches the dataset into memory */
    virtual int get_item () = 0; /* --- read an item */
    virtual int get_iset () = 0; /* --- read an item set */
    // void prepare (); /* --- sort set and remove duplicates */
    protected:
    std::vector<ITEMSET> isets; /* item set vector */
    int isetsz; /* number of itemsets */
    ITEMSET cis; /* current item set */
    int reccnt; /* number of records read */
    bool load; /* flag for file-buffering */
    int maxcnt; /* maximal number of items per set */
    int curr; /* current record read */
    int pos; /* starting reading position in file */
    char* fn_in; /* file name */
    };



    inline int File::items()
    {
    return nimap.size();
    }

    inline bool File::loaded()
    const{
    return load;
    }

    inline int File::size() const{ /* get the number of itemset */
    return isetsz; /* currently loaded */
    }



    inline const char* File::lookup(int id) /* get the name of a given
    identifier*/
    const{
    return nimap.lookup(id);

    }

    inline const char* File::looktr(int id) /* get the name of a given
    transaction*/
    const{
    return trmap.lookup(id);

    }

    inline SymTab& File::symbols() /* gets the symbol table */
    {
    return nimap;
    }

    #endif

    --------------------------------------

    I have a problem at runtime in

    File::~File()
    {
    if (file)
    std::fclose(file);
    if (fn_in)
    delete[] fn_in;
    }

    Segmentation fault when std::fclose(file) is executed, I don't
    understand why...

    Here some details:

    ----------

    (gdb) #0 0x00000000 in ?? ()
    (gdb) #1 0x400e710d in fclose@@GLIBC_2.1 () from /lib/libc.so.6
    (gdb) #2 0x0804b86a in File::~File (this=0x8072c18, __in_chrg=0) at
    .../File.cpp:26
    (gdb) #3 0x0805bca2 in AsciiFile::~AsciiFile (this=0x8072c18,
    __in_chrg=3)
    (gdb) at ../AsciiFile.h:19

    ----------------------------------------

    I remember to you that it is a Linux porting from a Win32 version, no
    problems there.

    Thanks to everybody,

    V.B.
    Italy
     
    VB, Jan 12, 2005
    #1
    1. Advertising

  2. VB wrote:
    >

    [snip]
    >
    > Segmentation fault when std::fclose(file) is executed, I don't
    > understand why...


    I didn't run your program and didn't analyze it. But:
    A segmentation fault is in 99% of all cases an indication
    that you somewhere screewed up the memory management. Either
    by using a 'pointer in the wood' or by accessing an array out
    of bounds.
    Anyway, it is often the case, that the point where the segmentation
    fault is recorded is not identical to where the real problem is
    located. What you see are just the symptoms, not the cause.

    Strategy: Remove everything from the program and start minimal.
    (eg. by commenting lots of code)
    Does it run?
    If yes, then add more code to it.
    Do this until the problem shows up again.
    A good guess is then, that the real cause is somehow related to
    the code section you activated last.

    Good luck. Things like that are hard to debug.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Jan 12, 2005
    #2
    1. Advertising

  3. VB

    Old Wolf Guest

    > File::File(const char* filename, bool ld)
    > {
    > fn_in = new char[strlen(filename)+1];
    > std::strcpy(fn_in,filename);
    >
    > load = ld;
    > maxcnt = isetsz = 0;
    > curr = reccnt = 0;
    > // bufsid = -1;
    > }
    >
    > File::~File()
    > {
    > if (file)
    > std::fclose(file);
    > if (fn_in)
    > delete[] fn_in;
    > }
    >
    > Segmentation fault when std::fclose(file) is executed, I don't
    > understand why...


    You haven't given a compilable code example, so it's hard for anyone
    to reproduce your results. Bot one thing does stand out: you
    never initialize 'file'. So if you create and then destroy a
    File object then you will call fclose with an uninitialized
    pointer (which could cause a segfault).

    BTW you would be better off to use a std::string for fn_in,
    instead of using new/delete.
     
    Old Wolf, Jan 12, 2005
    #3
  4. VB

    Ron Natalie Guest

    Old Wolf wrote:
    d why...
    >
    >
    > You haven't given a compilable code example, so it's hard for anyone
    > to reproduce your results. Bot one thing does stand out: you
    > never initialize 'file'. So if you create and then destroy a
    > File object then you will call fclose with an uninitialized
    > pointer (which could cause a segfault).
    >

    Further, there's all this owned object (pointers and the FILE*)
    managed by the constructor and destructor, yet there's no copy constructor
    and copy assignment operator.

    The whole thing is a very bad design.
     
    Ron Natalie, Jan 15, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Anks

    Why segmentation fault

    Anks, Sep 13, 2003, in forum: C Programming
    Replies:
    3
    Views:
    600
    The Real OS/2 Guy
    Sep 14, 2003
  2. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,214
    Smokey Grindel
    Dec 2, 2006
  3. CBFalconer

    Re: fclose cause segmentation error

    CBFalconer, Feb 17, 2005, in forum: C Programming
    Replies:
    2
    Views:
    373
    Kenneth Brody
    Feb 17, 2005
  4. Rob Morris

    Re: fclose cause segmentation error

    Rob Morris, Feb 17, 2005, in forum: C Programming
    Replies:
    0
    Views:
    513
    Rob Morris
    Feb 17, 2005
  5. Rufus V. Smith

    Re: fclose cause segmentation error

    Rufus V. Smith, Feb 17, 2005, in forum: C Programming
    Replies:
    0
    Views:
    377
    Rufus V. Smith
    Feb 17, 2005
Loading...

Share This Page