Passing if/ofstream objects by reference

This is a discussion on Passing if/ofstream objects by reference within the C++ Programming forums, part of the General Programming Boards category; I've been having a persistent problem about something I really really don't understand: I'm using the ifstream and ofstream objects ...

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    13

    Passing if/ofstream objects by reference

    I've been having a persistent problem about something I really really don't understand:

    I'm using the ifstream and ofstream objects to read to and write from files. They seem to work fine provided I declare the stream, do what I want with it and close it all in one block of code.

    But when I pass the things by reference to other functions, they begin to act unpredictably. The program compiles and then is instantly closed by Windows, or it just hangs and stops responding. Oddly, it works perfectly when run in debug mode, but not when properly compiled.

    This problem has recurred throughout many different projects and so I've not included any code. I'm assuming it's something to do with the internal code of ifstream/ofstream or some other factor about which I'm unaware.

    Any ideas?

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    It should work fine if you truly are passing by reference. You might get issues if you don't pass by reference (actually you should get compiler errors) or if you re-declare variables in the functions that hide the passed in ones.

    Your best bet is to make the smallest, simplest, example that demonstrates the problem, then post the full code and input you give it.

  3. #3
    Registered User
    Join Date
    Oct 2005
    Posts
    13
    Okay, well, for an example here's a cut-down of a random name generator I was trying to make- I was using a txt file called namlib.txt which was full of names, separated by headers like &&SURNAME or &&NICKNAME, which the program picked up on as 'nametype's.
    Code:
    #include <iostream>
    #include <fstream>
    #include <stdlib.h>
    #include <cstdarg>
    using namespace std;
    
    int GetRand(int min, int max);//random numbers in a range
    
    void fillpool(char** pool,char* nametype);//fills pool with the right kind of names
    int number_names(char* nametype);//returns how many of a certain type of name in a pool in the txt file.
    
    char* generateName(int args,...);
    
    int main(){
    
        while(1){
        cout<< generateName(3,"&&GIVEN","&&NICKNAME","&&SURNAME");
        cin.get();
        }        
    }    
    
    
    char* generateName(int args,...){
        
        va_list arguments;//stores arguments passed to function.
        va_start ( arguments, args );// va_start is a macro to initialise all arguments after args.
    
        //initialise pool and string.
        char** pool;//pool for names
        char* namestring;//holds final name.
        namestring = new char[256];
        namestring[0]='\0';
        int i;//to access elements in pool
    
        for (int arg=0; arg<args; arg++){
    
            char* a= va_arg ( arguments, char* ); // va_arg is an argument. of type char*.
        
            pool=new char*[number_names(a)];//create space in pool.
            fillpool(pool,a);//fill space in pool.
            
            i= GetRand(0,number_names(a)-1);//access random element from pool
            strcat(namestring,pool[i]);//add element to namestring.
            //delete pool;//clean up memory left in pool.
        }
        //end:
        //va_end ( arguments );                  // Cleans up the list
        return namestring;
    }    
    
    
    void fillpool(char** pool,char* nametype){
        
        //variables:
        ifstream library;   //accesses the name bank txtfile
        int range =0;   //determine whether to read in names.
        int e=0;    //access elements of the pool array.
        char* name;    //to hold the name from namlib.
        name = new char[256];    //assign bytes to name.
        
        //ensure name bank is open and ready.
        if ( !library.is_open() ){
            library.open("namlib.txt");
        }    
        library.clear();//reset flags
        library.seekg(0,ios::beg);//reset get pointer
        
        while (!library.eof()){
            
            //when out of range:
            if (!range){
                library.getline(name,256);    //buffer name
                
                //test name against nametype.
                if (strcmp(name,nametype)==0){
                    range=1;//now in range
                }    
                
            }    
            
            //when in range:
            if (range){
                library.getline(name,256);            //buffer name
                        
                //check if still in range:
                if (strstr(name,"&&") ){//all nametypes will begin with "&&" so this is the check.
                    range=0;
                }    
                
                else {
                    //add a new string element to the pool.
                    pool[e]=new char[256];//assign space.
                    char* pname;//create a pointer
                    pname=pool[e];//point to assigned space
                    strcpy(pname,name);//fill required space
                    e++;//point to next element in pool.
                    pname=0;//reset stray pointer
                }    
                
            }//end of in range block
            
        }//end of !library.eof() block
    
    }//end of fillpool function
    
    
    int number_names(char* nametype){
    
    //variables:
        ifstream library;   //accesses the name bank txtfile
        int range =0;   //determine whether to read in names.
        int e=0;    //count names
        char* name;    //to hold the name from namlib.
        name = new char[256];    //assign bytes to name.
        
        //ensure name bank is open and ready.
        if ( !library.is_open() ){
            library.open("namlib.txt");
        }    
        library.clear();//reset flags
        library.seekg(0,ios::beg);//reset get pointer
        
        while (!library.eof()){
            
            //when out of range:
            if (!range){
                library.getline(name,256);    //buffer name
                
                //test name against nametype.
                if (strcmp(name,nametype)==0){
                    range=1;//now in range
                }    
                
            }    
            
            //when in range:
            if (range){
                library.getline(name,256);            //buffer name
                        
                //check if still in range:
                if (strstr(name,"&&") ){//all nametypes will begin with "&&" so this is the check.
                    range=0;
                }    
                
                else {
                    //count names
                    e++;
                }    
                
            }//end of in range block
            
        }//end of !library.eof() block    
        
        return e-1;//arrays start at 0.
        
    }    //end of function number_names
    In this example, the program hangs. When I comment out
    Code:
    library.open("namlib.txt");
    in the function fillpool(), it runs without any problem.
    Last edited by evilkillerfiggi; 12-10-2005 at 04:16 AM.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    If you could give an example input file it would help.

    One thing I did see is this:
    Code:
    return e-1;//arrays start at 0.
    You are using the return value of that as the size of the array you are creating with this line:
    Code:
    pool=new char*[number_names(a)];//create space in pool.
    Array indexes start at zero, but the size you pass to new[] still must be the number of elements in the array. So if you find 3 names (e is 3) you should return 3 and create an array of size 3. Then, when you use the array you will be using indexes 0, 1 and 2.

    It is possible that is your entire problem. By commenting out the call to open in fillpool, you are just skipping all that code (because reading fails immediately on an unopened file). If you actually open the file, then the code runs you go past the bounds of the pool array because you created it one size too small.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Using Vectors. MinGW warning
    By Viewer in forum C++ Programming
    Replies: 9
    Last Post: 03-26-2009, 03:15 PM
  2. passing local objects by reference
    By manav in forum C++ Programming
    Replies: 15
    Last Post: 03-31-2008, 07:32 AM
  3. Question about OpenGL/Linux
    By Ideswa in forum Linux Programming
    Replies: 12
    Last Post: 09-10-2006, 05:56 AM
  4. Passing variables by reference
    By Tonto in forum C++ Programming
    Replies: 0
    Last Post: 07-16-2005, 12:56 AM
  5. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 09:18 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21