LoadImage - Memory access violation

Monkey Forums/Monkey Beginners/LoadImage - Memory access violation

radiata(Posted 2014) [#1]
So I can't figure out the cause of this error. LoadImage is throwing a memory access violation if it gets used outside of a field declaration.

Class HoldImage
	Field img:Image
	
	Method New()
		img = LoadImage("/img/janitor.png")
	End
End

Function Main()
	Local temp:HoldImage = New HoldImage
End


Is throwing the error. It points to the second line here:
Function LoadImage:Image( path$,frameCount=1,flags=Image.DefaultFlags )
	Local surf:=device.LoadSurface( FixDataPath(path) )


However, if I move LoadImage to the field declaration as follows it works just fine:

Class HoldImage
	Field img:Image = LoadImage("/img/janitor.png")
	
	Method New()

	End
End

Function Main()
	Local temp:HoldImage = New HoldImage
End


Really not sure what's going on or how to fix it.

Additional info: desktop target, Monkey x77a. Not sure if either of those will be helpful for diagnostic purposes.


Gerry Quinn(Posted 2014) [#2]
I think you are probably trying to load images without getting mojo started up (by creating a class based on App). There's a lot of stuff that has to get up and running before you can call mojo graphic commands.

The field version should fail too, but maybe it fails silently for some reason.


therevills(Posted 2014) [#3]
With your first version with loading the image via the ctor, it means every single time you instaniate the object you will be loading the image which I'm sure you don't want.

Where were you call the ctor in the main app? As I think Gerry is correct.

What I normally do is store the graphics in a map before I need them and pass them around to whatever objects require them.


radiata(Posted 2014) [#4]
Thanks for both responses.

That was pseudocode that was apparently missing some important parts. Sorry about that, I'm fairly new to programming. It seems like loading some kind of media in an overloaded New function is causing the access error The actual code I've been working on is what you mentioned, a map that holds everything with methods to pull out references.

This illustrates what I found the problem was, on the desktop target it gives the memory access violation:
Import mojo

Class HoldImage Extends App
	Field img:Image
	
	Method New()
		SetUpdateRate = 30
		img = LoadImage("janitor.png")
	End
	
	Method OnRender()
		DrawImage img, 30, 30
	End
End

Function Main()
	Local temp:HoldImage = New HoldImage
End


And this is the code that works. All that was changed is changing the method from New to OnCreate:
Import mojo

Class HoldImage Extends App
	Field img:Image
	
	Method OnCreate()
		SetUpdateRate = 30
		img = LoadImage("janitor.png")
	End
	
	Method OnRender()
		DrawImage img, 30, 30
	End
End

Function Main()
	Local temp:HoldImage = New HoldImage
End


It's nice to solve the problem but I still have no clue why the first version is throwing a memory violation.


Jesse(Posted 2014) [#5]
look at the native code created for the platform you are compiling. it should give you an idea of what is going on. mainly there is a method that is executed from the "App" part of the game/application that is executed before the instructions in the "New" method of "HoldImage" is executed. therefore the setUpdateRete and "ing = LoadImage(****)" are never executed because it never gets that far. The "New" on the "App" part is executed and is what is calling the "OnCreate", "OnRender"etc... and since "img" is never initialize when the "OnRender" is called you get a MAV.


therevills(Posted 2014) [#6]
Due to the setup of the graphics context with Mojo, when you try to load the image resource in the ctor of HoldImage the graphics context has not been set up yet and therefore causes the MAV (memory access violation).

When you load your images it must be on or after OnCreate of the App class.


Gerry Quinn(Posted 2014) [#7]
In this case none of the main App stuff gets set up at all because in HoldImage.New() you have not called Super.New(), i.e. App.New().

I think if you called it as the first statement in HoldApp.New() things would actually work, but it is an untidy way to go about it.

The App class is not special in any way language-wise, but it is kind of special in the way you use it. It is best to just set it up at the start and mostly only write OnXXX() overrides until you understand things well. The OnXXX methods are empty unless overridden, so there is no need to call the Super version of those. It makes it easy to get started *unless* you try to be fancy, and then it is possible to become confused!