2

I am trying to use a FILE pointer multiple times through out my application for this I though I create a function and pass the pointer through that. Basically I have this bit of code

     FILE* fp;
    _wfopen_s (&fp, L"ftest.txt", L"r");
    _setmode (_fileno(fp), _O_U8TEXT);
    wifstream file(fp);

which is repeated and now instead I want to have something like this:

wifstream file(SetFilePointer(L"ftest.txt",L"r"));
....
wofstream output(SetFilePointer(L"flist.txt",L"w"));

and for the function :

FILE* SetFilePointer(const wchar_t* filePath, const wchar_t * openMode)
{
    shared_ptr<FILE> fp = make_shared<FILE>();
    _wfopen_s (fp.get(), L"ftest.txt", L"r");
    _setmode (_fileno(fp.get()), _O_U8TEXT);
    return fp.get();
}

this doesn't simply work. I tried using &*fp instead of fp.get() but still no luck.

halfer
  • 19,824
  • 17
  • 99
  • 186
Hossein
  • 24,202
  • 35
  • 119
  • 224
  • 1
    Maybe [this idea](http://codereview.stackexchange.com/questions/4679/shared-ptr-and-file-for-wrapping-cstdio-update-also-dlfcn-h) is of interest to you. – Kerrek SB Jul 21 '13 at 11:27
  • Thanks , but there you are converting a File* to a shared_ptr, i am using a shared_ptr and im stuck how to reverse it.! I am clueless :-/ – Hossein Jul 21 '13 at 11:44
  • 3
    Well, your approach simply makes no sense. When you say `make_shared`, you're effectively saying `new FILE`, which is totally wrong, since `FILE` is an *opaque* type. – Kerrek SB Jul 21 '13 at 11:57
  • So what should i do then? i dont want to have repeated code , i cant think of any other way! i would be grateful if you can further guide me on this – Hossein Jul 21 '13 at 12:26

1 Answers1

3

You aren't supposed to create FILE instances with new and destroy them with delete, like make_shared does. Instead, FILEs are created with fopen (or in this case, _wfopen_s) and destroyed with fclose. These functions do the allocating and deallocating internally using some unspecified means.

Note that _wfopen_s does not take a pointer but a pointer to pointer - it changes the pointer you gave it to point to the new FILE object it allocates. You cannot get the address of the pointer contained in shared_ptr to form a pointer-to-pointer to it, and this is a very good thing - it would horribly break the ownership semantics of shared_ptr and lead to memory leaks or worse.

However, you can use shared_ptr to manage arbitrary "handle"-like types, as it can take a custom deleter object or function:

FILE* tmp;
shared_ptr<FILE> fp; 
if(_wfopen_s(&tmp, L"ftest.txt", L"r") == 0) {
  // Note that we use the shared_ptr constructor, not make_shared
  fp = shared_ptr<FILE>(tmp, std::fclose);
} else {
  // Remember to handle errors somehow!
}

Please do take a look at the link @KerrekSB gave, it covers this same idea with more detail.

halfer
  • 19,824
  • 17
  • 99
  • 186
JohannesD
  • 13,802
  • 1
  • 38
  • 30