Thread: Passing ifstream object between functions

  1. #1
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181

    Passing ifstream object between functions

    Code:
    void lexer(ifstream& inputfile)
    {
        string line;
        getline(inputfile,line);
    }
    
    ifstream& inputbuffer()
    {
        ifstream inputfile;
        inputfile.open ("C:\\Product Description.txt");
        return inputfile;
    }
    
    int main()
    {
        lexer(inputbuffer());
        return 0;
    }
    Im trying to pass inputfile between two functions. The code compiles but immediately upon running the program, there is a "bad cast" run time error. Can anyone explain whats the problem and what is missing in my code to correct this?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You are returning a reference to a local variable. That is a Bad Thing. I suggest that you just get rid of the inputbuffer function, e.g., write:
    Code:
    ifstream inputfile("C:\\Product Description.txt");
    lexer(inputfile);
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181
    Ill look into trying that just now. But before trying, what about the other two options:

    1) Instead of returning by reference, I return a pointer. I guess this doesn't help at all does it, because the pointer will still try point to a local variable that's out of scope.
    2) What about allocating the inputfile object into the heap, through new/malloc, then returning a reference or pointer to it?

  4. #4
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by Vespasian View Post
    2) What about allocating the inputfile object into the heap, through new/malloc, then returning a reference or pointer to it?
    That is fine (though a little cumbersome) as long as you remember to delete that after use.
    You can also use a smart pointer for this (std::unique_ptr , in this case), for which you do not have to manually delete it.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Vespasian
    1) Instead of returning by reference, I return a pointer. I guess this doesn't help at all does it, because the pointer will still try point to a local variable that's out of scope.
    Indeed, returning a pointer to a local variable has the same problem: the object no longer exists once the function goes out of scope.

    Quote Originally Posted by Vespasian
    2) What about allocating the inputfile object into the heap, through new/malloc, then returning a reference or pointer to it?
    I wouldn't do that (and malloc should not be used here, except in special cases). Creating the object while opening the file is as easy as I have demonstrated (minus error handling). If there is something complicated in say, constructing the file name that should go into a function, write a function to return the file name.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181
    I know that heap allocation of ifstream is advised against, but for the sake of education, I tried allocating using new[] and using pointer to the newly allocated memory as seen below:

    Code:
    void lexer(ifstream* inputfile)
    {
        string line;
        getline(*inputfile,line);
    }
    
    ifstream* inputbuffer()
    {
        ifstream* inputfileptr = new ifstream[10];
        ifstream inputfile;
        inputfile.open ("C:\\Product Description.txt");
        *inputfileptr = inputfile;
        return inputfileptr;
    }
    
    int main()
    {
        lexer(inputbuffer());
        return 0;
    }
    I get a compiler error. The error message mentions:
    'std::ios_base& std::ios_base:perator=(const std::ios_base&)' is private
    It doesnt mention what line it is but actually opens up some very long 1000 line .cpp file that I assume is the class code for ifstream. When I blank out line 12, it seems to compile so I assume line 12 is the problem.
    Last edited by Vespasian; 03-29-2013 at 12:07 PM.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    ifstream objects are not copyable. Even if they were, it would make no sense to create ten of them when you only need one, and then create yet another one to assign to one of the ten. Oh, and you did not use delete (or rather delete[], in your case).

    You are probably after something like:
    Code:
    void lexer(ifstream* inputfile)
    {
        string line;
        getline(*inputfile, line);
    }
    
    ifstream* inputbuffer()
    {
        return new ifstream("C:\\Product Description.txt");
    }
    
    int main()
    {
        ifstream* inputfile = inputbuffer();
        lexer(inputfile);
        delete inputfile;
        return 0;
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181
    The code works, thanks, but I dont get the latter portion of your line 9.
    My understanding of new[] is that one needs to allocate sized chunks of memory, say, ifstream [10]. So Im kinda confused why theres a string in there?

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Vespasian
    My understanding of new[] is that one needs to allocate sized chunks of memory, say, ifstream [10].
    That would create 10 ifstream objects. If you want just one:
    Code:
    return new ifstream;
    Quote Originally Posted by Vespasian
    So Im kinda confused why theres a string in there?
    The same reason why I wrote:
    Code:
    ifstream inputfile("C:\\Product Description.txt");
    instead of:
    Code:
    ifstream inputfile;
    The string is there because it is the argument to the relevant constructor.

    Then, remember to delete what you new, and delete[] what you new[]. Then again, no: remember not to use new or new[] unless you are going to use it with a smart pointer, or are implementing at a lower level. Rather, use containers where appropriate, or in this case, just don't use new since you don't need it.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    In C++11, we have yet another option, which is moving the object:
    Code:
    void lexer(ifstream&& inputfile)
    {
        string line;
        getline(inputfile,line);
    }
     
    ifstream inputbuffer()
    {
        ifstream inputfile("C:\\Product Description.txt");
        return inputfile;
    }
     
    int main()
    {
        lexer(inputbuffer());
        return 0;
    }
    This is a little trickier, but the essence is that we take the state of the inputfile and move it from inputfile into a temporary constructed ifstream which is returned.
    Then--and here's another tricky thing--we pass that temporary to lexer. However, the problem is that we just got a temporary (put simply, a variable that does not have a name and have limited lifetime). A reference (ifstream&) cannot accept a temporary according to the rules, so we have to use an r-value reference, which essentially is a reference to a temporary.
    Now it works as expected, without the use of new and sidestepping your problems.

    It is a little more complex, though, and laserlight's solution of constructing the stream and passing it via reference works, too, and is probably a little easier.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Trouble storing ifstream object in pair object
    By Programmer_P in forum C++ Programming
    Replies: 7
    Last Post: 01-17-2012, 01:20 AM
  2. Replies: 6
    Last Post: 04-04-2010, 11:48 AM
  3. Passing object references to functions
    By circuitbreaker in forum C++ Programming
    Replies: 6
    Last Post: 02-09-2008, 12:21 PM
  4. how to pass an ifstream object to a function
    By chintugavali in forum C++ Programming
    Replies: 14
    Last Post: 12-18-2007, 09:58 PM
  5. how do i get the file pointer in a ifstream object?
    By mickey in forum C++ Programming
    Replies: 2
    Last Post: 10-21-2002, 01:50 AM

Tags for this Thread