Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Memory Access violation after program closes  (Read 9445 times)

0 Members and 1 Guest are viewing this topic.

Shilo

  • Newbie
  • *
  • Posts: 5
    • View Profile
Memory Access violation after program closes
« on: July 17, 2008, 04:06:32 am »
I am trying to use a C++ style singlton class to manage my sf::Images.  I have used the same class on different projects with different data type ie not sf:Image   without any problems.
 
After I close the application using App.Close()  I get this:
Unhandled exception at 0x004a829b in SFML_Test.exe: 0xC0000005: Access violation reading location 0x00000004.

Visual Studio 2005 takes me to this code in xmemory.h
Code: [Select]

// TEMPLATE FUNCTION _Destroy
template<class _Ty> inline
void _Destroy(_Ty _FARQ *_Ptr)
{ // destroy object at _Ptr
_DESTRUCTOR(_Ty, _Ptr);
}


Here is the ImageManager class:
Code: [Select]

#pragma once
#ifndef IMAGE_MANAGER_H
#define IMAGE_MANAGER_H

#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window/Window.hpp>
#include <string>
#include <iostream>
#include <fstream>
#include <map>

typedef std::map<std::string, sf::Image> ImagePool;
std::string MEDIA_DIRECTORY = "Media/";

class ImageManager
{
public:
static ImageManager& GetInstance()
{
static ImageManager instance;
return instance;
}

sf::Image& GetImage(std::string filename )
{
if(images.count(filename) == 0)
{
std::string pathName = MEDIA_DIRECTORY + filename;

sf::Image img;
if (!img.LoadFromFile(pathName))
{
std::cout << "Couldn't load image " << filename << std::endl;
}

images[filename] = img;
}
   
//Return the image
return images[filename];
}

~ImageManager() {}

private:
ImageManager(void) {};
ImageManager(const ImageManager&);
ImageManager& operator=(const ImageManager&);

ImagePool images;
};

#endif



This class works in other applications, (ones that do not store sf::Images), so there is something strange going on with the way sf::Image deletes it's data.  Anyone with VS2005, give this a try, use this class to load your sf::Image and see what happens after you close the application.

Note:  I have already tried putting try..catch blocks around the destructor and around the App.Close function calls,   the access violation happens after the destructor and after App.Close.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Memory Access violation after program closes
« Reply #1 on: July 17, 2008, 04:37:49 am »
Are you using dynamic SFML libraries ? Are you linking the debug libraries (sfml-xxx-d) in debug mode, and the release ones in release mode ?
Laurent Gomila - SFML developer

Shilo

  • Newbie
  • *
  • Posts: 5
    • View Profile
Memory Access violation after program closes
« Reply #2 on: July 17, 2008, 05:14:28 am »
Quote from: "Laurent"
Are you using dynamic SFML libraries ? Are you linking the debug libraries (sfml-xxx-d) in debug mode, and the release ones in release mode ?


I am linking to the static libraries in debug mode.  ie
sfml-system-s-d.lib sfml-graphics-s-d.lib sfml-window-s-d.lib

I tried linking to the dynamic dll's at first, but the compiler kept complaining about not being able to find the .dll files,  even though they are in the same directory as the static lib's.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Memory Access violation after program closes
« Reply #3 on: July 17, 2008, 07:25:14 am »
DLLs need to be in the same directory as the executable.
Laurent Gomila - SFML developer

Shilo

  • Newbie
  • *
  • Posts: 5
    • View Profile
Memory Access violation after program closes
« Reply #4 on: July 17, 2008, 08:06:13 am »
Quote from: "Laurent"
DLLs need to be in the same directory as the executable.


Ok, I copied the following dll's to my project's directory and to it's Debug (executable directory)
sfml-system-d.dll sfml-window-d.dll sfml-graphics-d.dll

I also changed the Project's properties Linker Additional Dependencies to the above list.

When I compile I get:
1>sfml-system-d.dll : fatal error LNK1107: invalid or corrupt file: cannot read at 0x300

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Memory Access violation after program closes
« Reply #5 on: July 17, 2008, 08:25:38 am »
You must still link with the .lib files (but those without -s), not the .dll.
Laurent Gomila - SFML developer

Shilo

  • Newbie
  • *
  • Posts: 5
    • View Profile
Memory Access violation after program closes
« Reply #6 on: July 17, 2008, 08:48:51 am »
Quote from: "Laurent"
You must still link with the .lib files (but those without -s), not the .dll.


Eureka!  The singleton works correctly now.  I didn't realize the dynamic libraries needed to be used for singleton to work properly.

Thanks for your help  8)
-Shilo

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Memory Access violation after program closes
« Reply #7 on: July 17, 2008, 10:21:12 am »
Well, it should work even with static libraries, this is still a bug that I need to fix.
Laurent Gomila - SFML developer

dabo

  • Sr. Member
  • ****
  • Posts: 260
    • View Profile
    • http://www.dabostudios.net
Memory Access violation after program closes
« Reply #8 on: July 17, 2008, 01:19:46 pm »
I'm using the static-libraries without any problems. My class is a singleton as well.

Shilo

  • Newbie
  • *
  • Posts: 5
    • View Profile
Memory Access violation after program closes
« Reply #9 on: July 17, 2008, 10:08:18 pm »
Quote from: "dabo"
I'm using the static-libraries without any problems. My class is a singleton as well.


Yes, but is your singleton like mine listed above?  Or are you returning a pointer.  ie.
Code: [Select]

static ImageManager* GetInstance()
{
     if(instance == 0) { instance = new instance(); }
     return instance;
}


This version did not produce the access violation while using the static libs.  But I didn't want to use this version because there was a danger of memory leak.  I tried wrapping the pointer with a Boost::shared_ptr but that produced the same access violation at the end of the program.


Back to the original version in my post (using static libs).
When I was trying to track down the problem.  I put a cout message and _getche() in the ImageManager's destructor like this:
Code: [Select]

~ImageManager() { std::cout << "IM Destructor..." << std::endl; _getche(); }


After the call to App.Close(),  the window would close, leaving me with just the console.  The console showing my message "IM Dstructor..." and the prompt waiting for me to hit any key.  

Once I hit any key, the access violation occurred.

My main.cpp is typical: Psuedocode
Code: [Select]

int main() do
  initialize App
  sf::Sprite mySprite(ImageLoader::GetInstance().getImage(filename)));

  while(App.Open()) do  // Game Loop
      while(Events in Queue) do
         if(Event == Event.Close)
             App.Close;
              break;
      end while
     //my  render stuff
  end while

return EXIT_SUCCESS
//end main
   

Here is what I believe is going on:
1)  App.Close() is invoked, Performs it's window clean up stuff
2)  Game loop is exited
3)  The Sprites in main.cpp destructors are called
4)  The static ImageManager destructor is called
5)  Access Violation Occurs


Steps 3 and 4 might be reversed.    
When step 3 takes place the sf::Image's underlying texture, pixels, or videoresource is released.   Then in step 4  the application/system tries to release those same resources again.

This should not occur because the owner of the sf::Image is the std::map inside the static ImageManger.  The Sprites are only holding references to those Images.

Laurent,  I hope this is info is helpful.
And thanks to you and to all who develop SFML - very cool Library!!!

-Shilo