Thread: gggrrr, unknown problem with <fstream>

  1. #1
    Registered User
    Join Date
    Jul 2003
    Posts
    22

    gggrrr, unknown problem with <fstream>

    k, i'm gonna paste a bunch of code in here cause i'm not sure what is causing this to generate errors. my problem apears to be in
    void pkrEdit::export(string file)

    if i compile and run exfile gets written to 0 bytes, however if i single step the program it produces and access violation at the line of code

    ifAllPkr.read((char *)&buffer, FStruct[i].data_len1);

    hope someone can help with this.


    main.cpp
    Code:
    #include "pkr.h"
    
    
    int main()
    {
    	pkrEdit pk;
    	string *dirs;
    	string *files;
    	ofstream test;
    	test.open("test.txt", ios::binary | ios::app);
    	files = new string[pk.numfiles];
    	dirs = new string[pk.numdirs];
    	pk.GetDirs(dirs);
    	pk.GetFiles(files);
        pk.export(files[20]);
    }

    pkr.cpp

    Code:
    #include "pkr.h"
    
    pkrEdit::pkrEdit()
    {
    
    	ifAllPkr.open("ALL.PKR", ios::binary | ios::ate);
    
    	ifAllPkr.seekg(0, ios::beg);
    
    	ifAllPkr.read((char *)&HStruct, sizeof(HStruct));
    
    	DStruct = new PK_DIR_STRUC[HStruct.num_dirs];    //create an array of dir_structs and file_structs
    	FStruct = new PK_FILE_STRUC[HStruct.num_files];  //= the number of dirs and files
    
    	for(int i = 0; i < HStruct.num_dirs; i++)        //and populate said arrays
    	{
    		ifAllPkr.read((char *)&DStruct[i], sizeof(PK_DIR_STRUC));
    	}
    
    	for(i = 0; i < HStruct.num_files; i++)
    	{
    		ifAllPkr.read((char *)&FStruct[i], sizeof(PK_FILE_STRUC));
    	}
    	numfiles = HStruct.num_files;
    	numdirs = HStruct.num_dirs;
    
    //	ofAllPkr.open("ALL.PKR", ios::binary | ios::ate);
    //	ofAllPkr.seekp(0, ios::beg);
    }
    
    string * pkrEdit::GetDirs(string *dirs)
    {
    
    	for(int i = 0; i < HStruct.num_dirs; i++)
    	{
    	
    		dirs[i] = DStruct[i].path;
    
    	}
    	return(dirs);
    
    }
    
    string * pkrEdit::GetFiles(string *files)
    {
    	for(int i = 0; i < HStruct.num_files; i++)
    	{
    		files[i] = FStruct[i].name;
    	}
    	return(files);
    }
    
    void pkrEdit::import(char *oldFile, char *newfile)
    {}
    
    void pkrEdit::export(string file)
    {
    	char *buffer;
    	for(int i = 0; i < HStruct.num_files; i++)
    	{
    		if(file == FStruct[i].name)
    		{
                ifAllPkr.seekg(FStruct[i].data_offset);
    			buffer = new char[FStruct[i].data_len1];
    			ifAllPkr.read((char *)&buffer, FStruct[i].data_len1);
    			exFile.open(file.c_str(), ios::binary | ios::ate);
    			exFile.write(buffer, FStruct[i].data_len1);
    			exFile.close();
    			delete[] buffer;
    		}
    	}
    }
    pkr.h

    Code:
    #include <fstream>
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    typedef struct PK_HEAD_STRUC
    {
    	char ident[4];
    	int unknown;// always 1
    	int num_dirs;
    	int num_files;
    }
    PK_HEAD;
    
    typedef struct PK_DIR_STRUC
    {
    	char path[32];
    	int file_offset;
    	int file_count;
    }
    PK_DIR;
    
    typedef struct PK_FILE_STRUC
    {
    	char name[32];
    	int unknown; // always -2
    	int data_offset;
    	int data_len1;
    	int data_len2; // always == data_len2
    }
    PK_FILE;
    
    
    class pkrEdit 
    {
    public:
    	int numfiles;
    	int numdirs;
        pkrEdit();
    	string *GetDirs(string *dirs);
    	string *GetFiles(string *files);
    	void import(char *oldFile, char *newFile);
    	void export(string file);
    
    protected:
    	PK_HEAD_STRUC HStruct;
    	PK_DIR_STRUC *DStruct;
    	PK_FILE_STRUC *FStruct;
    private:
    	ofstream exFile;
    	ifstream imFile;
    	ofstream ofAllPkr;
    	ifstream ifAllPkr;
    
    	
    };






    ps. thanks in advance for any help.
    btw, i know i still need to go back and cleanup a lot of the memory i allocated just havn't got around to it yet
    Last edited by axlton; 07-25-2003 at 04:24 PM.

  2. #2
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>ifAllPkr.read((char *)&buffer, FStruct[i].data_len1);
    Try:
    >>ifAllPkr.read((char *)buffer, FStruct[i].data_len1);
    Note the lack of &
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  3. #3
    Registered User
    Join Date
    Jul 2003
    Posts
    22
    still the same, after single steping some more and shuffling some code around i've found that the problem is partialy realated to

    FStruct[i].data_len1

    as in

    ifAllPkr.read((char *)&buffer, FStruct[i].data_len1);

    i have verified that FStruct[I].data_len1 is a valid integer
    and is being read properly in the class constructor.
    so why it should generate an error is beyond me.

    however, i have noticed that if i replace all the references
    to FStruct[i].data_len1 and replace them with integers such as

    ifAllPkr.read((char *)&buffer, 500);

    then the read operation is succesfull but
    i then get another access violation from
    the exfile.open() statement.

    hope that made some sense , this has been driving me mad all day

    [edit]
    after playing around with it a bit more i found that removing the & does kind of work however, the first 120,000 someodd bytes of the output file are blank, after that everything is hunky dorey.
    any ideas?
    [/edit]
    Last edited by axlton; 07-25-2003 at 07:48 PM.

  4. #4
    Registered User
    Join Date
    Jul 2003
    Posts
    22
    success!!! but i'm at a loss as to explain why.
    so here's my revised code if anyone cares to take a crack at
    telling me why one works and not the other i'd really aprieciate it.

    new code

    Code:
    void pkrEdit::export(string file)
    {
    	char *buffer;
    	for(int i = 0; i < HStruct.num_files; i++)
    	{
    		if(file == FStruct[i].name)
    		{
    		         ifAllPkr.seekg(FStruct[i].data_offset, ios::beg);
    			buffer = new char[FStruct[i].data_len1];
    			ifAllPkr.read((char *)buffer, FStruct[i].data_len1);
    			cout<<FStruct[i].data_len1;
    			exFile.open("file.c_str()", ios::binary | ios::ate);
    			exFile.write((char *)buffer, FStruct[i].data_len1);
                               exFile.close();
    			delete[] buffer;
    		}
    	}
    }

    old code

    Code:
    void pkrEdit::export(string file)
    {
         char *buffer;
         for(int i = 0; i < HStruct.num_files; i++)
        {
              if(file == FStruct[i].name)
             {
                    ifAllPkr.seekg(FStruct[i].data_offset);
                    buffer = new char[FStruct[i].data_len1];
                    ifAllPkr.read((char *)&buffer, FStruct[i].data_len1);
                    exFile.open(file.c_str(), ios::binary | ios::ate);
                    exFile.write(buffer, FStruct[i].data_len1);
                    exFile.close();
                    delete[] buffer;
               }
          }
    }
    Last edited by axlton; 07-25-2003 at 08:07 PM.

  5. #5
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    1) This was wrong, the & makes it mean something completely different.

    ifAllPkr.read((char *)&buffer, FStruct[i].data_len1);

    it should be

    ifAllPkr.read(buffer, FStruct[i].data_len1);

    buffer itself is a pointer to a character array -- that is, it holds the address of the array. &buffer is the ADDRESS of the address of the array (a char **). You cast it to a char *, but when it tries to write there, it's not writing into the buffer, it's writing onto the stack where the address of the buffer lived. You corrupt your stack and kill your program.

    The very fact it wouldn't compile without a cast should make you seriously question whether you were doing the right thing. Your compiler was smart enough to inform you that you were using a char** where a char* was needed, but you basically went over its head and told it to do it anyway.

    2) This line doesn't do what you think it does:

    exFile.open("file.c_str()", ios::binary | ios::ate);

    This does not open the file whose name is stored in the string file, it opens a file that is actually named "file.c_str()" in the current directory. If it crashed before, it might be because the string within file was garbage.

    3) This is a useless cast:

    exFile.write((char *)buffer, FStruct[i].data_len1);

    buffer's type is already char *, there's no need to convert it. Just do:

    exFile.write(buffer, FStruct[i].data_len1);

  6. #6
    Registered User
    Join Date
    Jul 2003
    Posts
    22
    hey, thanks for the help


    grrr, gotta start looking over my code more carefully before i post though

    exFile.open("file.c_str()", ios::binary | ios::ate);

    for a minute there i was thinking that fstream couldn't accept
    file.c_str so i just quickly enclosed it in quotes to see if it would would accept a normal string or if there was something else wrong there. but i forgot to get rid of the quotes when i was done. embarassing

    anyway thanks once again to both of you for helping me out.
    Last edited by axlton; 07-25-2003 at 11:21 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  2. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  3. Unknown problem
    By Mindphuck in forum C Programming
    Replies: 3
    Last Post: 04-08-2006, 02:35 PM
  4. Laptop Problem
    By Boomba in forum Tech Board
    Replies: 1
    Last Post: 03-07-2006, 06:24 PM
  5. Unknown problem
    By pink_langouste in forum Windows Programming
    Replies: 2
    Last Post: 12-04-2002, 12:36 AM