Here are some recent examples that I prepared for Lee for the 6.7 bug fix release, simplest first. All were originally based upon existing bug reports in this forum which were re-written to make the bug easier for Lee to see and confirm a fix on.
Example 1.
Compile and run - the code will fail at runtime with 'Runtime Error 7002 - Could not load mesh at line 3'
Should report 'Runtime Error 7007 - Object already exists at line 3'
Make Object Cube 1, 1
Make Mesh From Object 1, 1
Make Object 1, 1, 0
Example 2.
Run the code. Press space to add another 100 sprites and hold the key down. On occasions, not all sprites will be displayed during the sync. Release the space key and they all appear.
This only appears to happen with multiples of 100 sprites.
sync on
sync rate 0
sync sleep 1
box 0, 0, 64, 64
get image 1, 0, 0, 64, 64
spr = 1
do
set cursor 0, 0
print "Sprite Count = "; spr - 1
if spacekey()
if keydown = 0
for i = 1 to 100
sprite spr,rnd(476)+100,rnd(396)+20,1
inc spr
next
endif
keydown = 1
sync
while spacekey()
endwhile
else
keydown = 0
endif
sync
loop
Example 3.
The OBJECT IN SCREEN function is inaccurate.
The code is designed to ensure that the object is always in wireframe mode if the object is visible.
1. Position the camera within the sphere. Rotate the camera within the sphere. Wireframe mode will pop on and off even though the object is always visible.
2. Press ENTER to reset the camera position & rotation. Rotate the camera so that the object and the bounding box is off-screen. Note that the OBJECT IN SCREEN result in the top-left of the display will still report '1'.
sync on
sync rate 60
sync sleep 1
autocam off
make object sphere 1, 50.0
set object cull 1, 0
show object bounds 1
position camera 0.0, 0.0, -150.0
xangle = 0
yangle = 0
repeat
if mouseclick()
xangle = 0
yangle = 0
position camera 0.0, 0.0, -150.0
endif
yangle = wrapvalue( yangle + mousemovex() )
yrotate camera yangle
xangle = wrapvalue( xangle + mousemovey() )
xrotate camera xangle
move camera ( upkey() - downkey() )
set object wireframe 1, object in screen(1)
set cursor 0, 0
print object in screen(1)
print str$( camera position x(), 2); "/"; str$( camera position y(), 2); "/"; str$( camera position z(), 2)
print xangle; "/"; yangle
sync
until spacekey()
Example 4.
Allocating an array of strings - the memory for the strings is not recovered when the array is undim'd or emptied. The memory for the actual array storage is returned Ok.
sync sleep 1
print " Just starting up ... ";
print "memory available = "; system smem available()
print "Allocating large number array ... ";
dim b(1000000)
print "memory available = "; system smem available()
print " Deallocating the array ... ";
undim b()
print "memory available = "; system smem available()
print ""
print "Allocating large string array ... ";
dim a$(1000000)
for i = 0 to 1000000
a$(i) = "This is just a long string and can contain any old crap ... and in fact it does!"
next
print "memory available = "; system smem available()
print " Deallocating the array ... ";
undim a$()
print "memory available = "; system smem available()
print ""
type MyType1
a as integer
endtype
print " Allocating number type array ... ";
dim c(1000000) as MyType1
print "memory available = "; system smem available()
print " Deallocating the array ... ";
undim c()
print "memory available = "; system smem available()
print ""
type MyType2
a as string
endtype
print " Allocating string type array ... ";
dim d(1000000) as MyType2
for i = 0 to 1000000
d(i).a = "This is just a long string and can contain any old crap ... and in fact it does!"
next
print "memory available = "; system smem available()
print " Deallocating the array ... ";
undim d()
print "memory available = "; system smem available()
print ""
wait key
This was originally rejected by Lee - he wasn't convinced:
Quote: "The issues regarding memory leaks reported using SMEM and Task Manager are not so clear cut, as both these do not reflect the true heap consumption of a DBP app, simply a determination of available physical memory on the overall machine."
Eventually, I managed to convince his with the following:
The code attached allocates a 100MB string, dims a string array, copies the string into it, then undims the array.
If there's no leak, then the code should run forever - there's going to be a little heap memory fragmentation, but not enough to stop this program until it has run though at least a couple of thousand loops (windows uses a best-fit allocator IIRC).
If there is a leak, the program will exit before it gets to 2000MB allocated and will probably exit earlier - mine dies after allocating 1200MB and when attempting to create the array for the next pass.
ChunkSize = 100
BigString$ = space$(1024*1024*ChunkSize)
Count = 0
Allocation = 0
do
inc Count
print "Allocation "; Count; " ("; Count*ChunkSize; ")"
` Allocate an array and set it's contents to the string
dim b$(0)
b$(0) = BigString$
` If it's empty at this point then probably ran out of memory
if b$(0) = "" then exit
` Free the array and do it again
undim b$()
loop
` Make some space so we can hopefully continue
BigString$ = ""
print "Failed to create a new string"
wait key
end
The last turned into a bit of a story, but it shows sometimes how far you may need to go to prove a bug is really there.