Segmentation Fault in fclose()...why?

V

VB

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
 
K

Karl Heinz Buchegger

VB said:
[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.
 
O

Old Wolf

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.
 
R

Ron Natalie

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,821
Latest member
AleidaSchi

Latest Threads

Top