SFML community forums

Help => System => Topic started by: Tamico on October 06, 2013, 09:57:35 pm

Title: Unable to free memory when using toAnsiString()
Post by: Tamico on October 06, 2013, 09:57:35 pm
I'm having an issue when using toAnsiString() in conjunction with std::ofstream. The function runs fine until it returns, in which case it crashes.

Here's the minimal code:

#include <SFML/System.hpp>
#include <fstream>
#include <string>

int main()
{
        // You could replace OUTPUT/OUTPUT.txt with your existing home directory
        sf::String filepath = "OUTPUT/OUTPUT.txt";
       
        // I suspect this is what is causing problems
        std::string tempout = filepath.toAnsiString();
       
        std::ofstream fileoutput ( tempout.c_str() );
       
        if (fileoutput.is_open())
        {
                fileoutput << "Output";
        }
}

The text file is created and contains "Output", but the program crashes on exit.

Here is the setup I'm using:

OS: Wndows 7 (64-bit)
Graphics device: Intgrated Intel graphics
SFML: v2.1 standard release (dynamically linked)
Compiler: Visual C/C++ 2010 (32-bit) -- compiled directly from the command prompt

I've also run the code in WinDbg. I get this when main() returns:

1   HEAP[minimal.exe]: Invalid address specified to RtlFreeHeap( 00550000, 005A3808 )
2   (d28.1070): WOW64 breakpoint - code 4000001f (first chance)
3   First chance exceptions are reported before any exception handling.
4   This exception may be expected and handled.
5   ntdll32!RtlpBreakPointHeap+0x23:
6   77950574 cc              int     3


Any help is appreciated.
Title: Re: Unable to free memory when using toAnsiString()
Post by: Ixrec on October 06, 2013, 11:24:05 pm
On my system the file open operation simply fails (btw, you really should be checking if it failed or not).  I assume it's because the OUTPUT folder doesn't already exist, because when I change the filepath to just "output.txt" the program runs just fine, and the word "output" does appear in that file.  No weird crashes or corruptions or warnings or anything.

Does closing the file yourself before the program ends change anything?
Title: Re: Unable to free memory when using toAnsiString()
Post by: Tamico on October 07, 2013, 12:05:00 am
The folder needs to exist and it needs to be accessible by the program (i.e. no administrator privileges). Writing only the file name "OUTPUT.txt" (no path) works fine. The crash only happens when a path is specified.

Having close() after the output doesn't seem to make a difference.
Title: Re: Unable to free memory when using toAnsiString()
Post by: Ixrec on October 07, 2013, 12:40:46 am
Then it sounds like this is as simple as improving your error checking and learning how to tell the system to make a directory.

Unfortunately SFML doesn't do anything with filesystems for you, but when I had to do this it turned out to be little more complicated than:
#ifdef _WINDOWS
        CreateDirectory(dirname.c_str(), NULL);
#else
        mkdir(dirname.c_str(), 0755);
#endif
 
I'll let you figure out the details with headers and exact types and encodings.
Title: Re: Unable to free memory when using toAnsiString()
Post by: Tamico on October 07, 2013, 12:56:03 am
The purpose is not to create a directory. The path already exists. (Just replace my example path with an existing directory)

EDIT: I really think my problem has something to do with using dividers in toAnsiString().
Title: Re: Unable to free memory when using toAnsiString()
Post by: Ixrec on October 07, 2013, 01:18:34 am
On my end if the path already exists the code also works fine.  I even cout'd the result of toAnsiString() and it looks exactly like it should.

What have you found that makes you think the slashes are a problem?  Assuming it's still the file open operation that's failing, have you checked what std::strerror(errno) produces?
Title: Re: Unable to free memory when using toAnsiString()
Post by: Tamico on October 07, 2013, 01:43:35 am
It's very bizarre. I'm getting "No error" from strerror(errno).

I did a little bit of testing and found that including "std::string tempout = filepath.toAnsiString();" causes the program to crash on exit even if I don't use tempout after that line.

EDIT: As soon as I remove "std::string tempout = filepath.toAnsiString();", the program exits smoothly. In all cases, OUTPUT.txt is always created with "Output" as text, even when the program crashes.
Title: Re: Unable to free memory when using toAnsiString()
Post by: Ixrec on October 07, 2013, 02:02:21 am
Well I'm pretty much out of ideas unless someone much smarter shows up.  You may be stuck using the standard strings.

Here's a few desperation suggestions:
-The only apparent difference in our setups is that you compile from command line, so maybe try compiling in the IDE like I do?
-Maybe try compiling SFML's source code along with your test program (dunno how hard setting up the dependencies is) on the off chance that lets you step through SFML's destructors or something.
Title: Re: Unable to free memory when using toAnsiString()
Post by: Tamico on October 07, 2013, 02:29:19 am
Thanks anyways for the help.

I don't really have an IDE, just the compiler executables, so compiling from the command prompt is all I can do.
I'll try what you suggested, and if that doesn't work, I'll try using the latest unofficial build.
Title: Re: Unable to free memory when using toAnsiString()
Post by: FRex on October 07, 2013, 02:36:53 am
You're probably mixing debug and release.
Quote
I don't really have an IDE, just the compiler executables
How (il)legal is this contraption? MS does provide legal express edition visuals free of charge and there is(are) other compiler(s) and IDEs(although they're a pile of configs, setups and incompatible builds(lol @ what is happening at most of threads on this forum about Code::Blocks cus of TDM + MinGW and SJLJ + DW2 exception handling models being all incompatible with each other), GCC is 100x smoother experience on Linux).
Title: Re: Unable to free memory when using toAnsiString()
Post by: eXpl0it3r on October 07, 2013, 02:39:03 am
Works fine on my end as well. (Windows 8.1, VS 10 x86)
Did make sure not to mix runtime library versions for SFML and the one you're using (aka mixing Debug and Release).

EDIT: I really think my problem has something to do with using dividers in toAnsiString().
What do you mean by "dividers"? Slashes?
Title: Re: Unable to free memory when using toAnsiString()
Post by: Tamico on October 07, 2013, 02:59:06 am
How (il)legal is this contraption?

Haha, I know. I'm using Microsoft's Windows SDK (http://msdn.microsoft.com/en-gb/windowsserver/ff851942), which includes raw compilers.

What do you mean by "dividers"? Slashes?

Yes. Although I'm probably just being an idiot with the path shenanigans.

Thanks for the help, guys. I'm setting up SFML from scratch, hope that helps.
Title: Re: Unable to free memory when using toAnsiString()
Post by: FRex on October 07, 2013, 03:28:37 am
This really looks like either problem with linking std libs(= different heaps and freeing across dll boundary = death) or mixing debug and release(= possibly different heaps and different size of standard templates in dll and your binary = death, possibly x2).