EXCEPTION_ACCESS_VIOLATION, I don't understand why

BlitzMax Forums/BlitzMax Beginners Area/EXCEPTION_ACCESS_VIOLATION, I don't understand why

ReconditePhreak(Posted 2011) [#1]
Ok, so I keep getting this and I don't understand why. I'm writing a crappy little tetris clone.

In essence I have a base Tetrimino class with a few abstract methods, and the classes representing the actual tetriminos classes inherit from it.

The Tetrimino class itself has a factory function that takes a type parameter and uses a switch to actually create the correct tetrimino object and return it.

The issue is that depending on where I call the Tetrimino.construct function, it will either succeed, or it will fail with an EXCEPTION_ACCESS_VIOLATION error, and I cannot see why.

I have a TetrisBoard object, and originally I had a method defined in said class called initializeNewTetrimino. One of the things it does is to call Tetrimino.construct as described above. If I call the initializeNewTetrimino method in the factory function for TetrisBoard, it throws the above error. If I manually construct the tetrimino in the factory function of TetrisBoard by calling the Tetrimino.construct call without calling initializeNewTetrimino, the call to Tetrimino.construct works just fine. In addition, if I manually call it, and *then* call the initializeNewTetrimino method that was failing earlier, it will succeed.

As a workaround I've take the initializeNewTetrimino method and made it a global level function that takes the TetrisBoard object as a parameter. Using this technique, it works flawlessly.

But I don't like not understanding why something like this is occuring. I'm a little tired, and I may just be missing something, but if I could get someone who is more experienced with blitzmax to look at the code, that would be awesome.

The files you'll be interested in are tetris_board.bmx, tetriminoes.bmx, and utils.bmx. If you look at lines 192 and 193 of tetris_board.bmx, you'll see where line 192 is commented out. The error will occur with the line commented, and it will disappear when the line is uncommented.

http://yivok.com/Test1.zip

I should also mention, I'm running this under Windows 7 x64

Also, just as a warning, I'm using this to learn BlitzMax so the code is messy and the way I'm using some of the types is very clunky. Especially how I'm representing the block coordinates. If you see something that can be improved please let me know. Just be aware that I know the overall architecture is not great, so I'm more interested in blitzmax specific things than architectural suggestions.

Last edited 2011


col(Posted 2011) [#2]
Hiya,
I haven't looked at your code just yet, I'm at work, but are you building in debug mode? This should prevent the EAV and stop your code at the line thats associated with the error giving you a huge clue as to what's gone wrong. You should see any variables in the pane on the right hand side once the debugger kicks in, and you can check values to verify they are what you're expecting.


ReconditePhreak(Posted 2011) [#3]
yes, it's specifically stopping on the Tetrimino.construct line, and I've checked everything all the way up the call chain. It's always possible that I'm missing something since I've been staring at it for so long, but everything looks to be in order.


col(Posted 2011) [#4]
Oh yes, we've all been there many times :)
I can take a look later after work.


ReconditePhreak(Posted 2011) [#5]
Thank you, I really appreciate it.


Jesse(Posted 2011) [#6]
your error is in your initialization of the tetrimino:
	Method initializeNewTetrimino()
		SeedRnd MilliSecs()
		Local nextType:Int = Rand(0, NUM_TETRIMINOES - 1)
		Self.tetrimino = Tetrimino.construct(nextType, gBucket)'******************************
		Local curr:Int = MilliSecs()
		
		nextDrop = calculateNextNormalDrop(curr)
		If Self.movingDown Then
			nextDrop = calculateNextSoftDrop(curr)
		End If
	End Method


the problem is that you are calling a variable "tetrimino" which is the same as the type "Tetrimino".
Blitzmax is not case sensitive so so "Tetrimono" and "tetrimino" are the same variable. FIrst it seems the compiler is not designed to handle that kind of problem which should have been automatically detected by the compiler as an error, and second since it doesn't know how to handle it, it crashes.

Last edited 2011


col(Posted 2011) [#7]
Hiya,

I think you'll find the compiler is getting confused because you have many Field member names the same as Type names. I'd suspect the reason for this crash in particular is that you have a field member of Tetrimino and a Type named Tetrimino with a valid function. The compiler could easily be trying to use the Field member ( which is initially null ) variable to execute the call to the function contained in the Tetrimino Type.
I'd try to keep all Type(s) and instances of those Types to have completely separate names.

For eg... a common format you'll see a lot of people use here is to place an extra 'T' in the Type name, so using some of your type names in your code you would have :-

Type TTetrimino
	Field bucket:TBucket
	
	'other fields and methods>
EndType

Type TBucket
	'more code
EndType


Also it looks as though you're thinking BMax distinguishes capital letters from smaller letters. It doesn't, meaning that 'bucket' is the same as 'Bucket'.
Once these little minor hiccups are corrected, you may find it works as expected.

EDIT :- Lol at the time zone cross over post! I've just repeated what Jesse posted! Apparently nearly an hour ago.

Last edited 2011


ReconditePhreak(Posted 2011) [#8]
Hey guys, thanks for the reply, I made the suggested changes and it fixed the issue.

I'm aware of the case sensitivity issue, the cap/noncap is more of a personal style (cap for types, non cap for non types[1]). I apparently don't completely understand the name lookup rules for BlitzMax, although I agree with Jesse, the compiler should be catching that error. I know better now :)

And especially thank you for the observation about prefixing types with T. I had noticed that convention and thought it was simply a variation of the CClass convention that MS liked to use at one point. I've never been a big fan of it, but in this case it looks like there's a practical reason for doing so. I'll be using the T convention in the future.

I would be interested to know if there's any documentation with regards to the name lookup rules for BlitzMax? I think that would be valuable for me to read through, if possible.

[1] lets pretend I'm not mixing camel case and underscores in my method names, bad bad bad...