Possible bug in structures with string member

Discussion specific to the DIP and TQFP packaged ZX devices like the ZX-40, ZX-44, ZX-32 and ZX-328 series. The differences between these devices is primarily the packaging and pinout so most issues will apply to all devices.
Post Reply
drapal
Posts: 25
Joined: 24 January 2006, 8:07 AM
Location: Denver

Possible bug in structures with string member

Post by drapal »

See the attached source. It crashes the ZX40. If I add more code, it will execute, but there is string corruption all over the place. Seems that it is related to AllocStr being on, and womething that looks like heap corruption.

Myron
Attachments
myproj.bas
single code file, add to a default project and run.
(1.05 KiB) Downloaded 2736 times
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

You are correct that the problem arises with an array of structures having a String member. The issue is not with string heap corruption, however. Rather, the problem is that the String members are not getting initialized properly. Only the String members of the first array element are initialized correctly. The String members of the remaining elements are not initialized. In this particular case, since the array was defined at the module level, the 4 bytes of storage for the string ends up being all zeroes, making the string look like a BasicX (statically allocated) string. That ends up causing lots of problems.

This problem has existed for some time; it was replicated using the v1.3.0 compiler as well.

One possible workaround is to temporarily switch to using bounded strings in the structure.

Code: Select all

Public Structure nvtable
	Public i as Integer
	Public s as BoundedString(25)
End Structure
A second possible workaround is to temporarily add some code to properly initialize the allocated String elements. Here is a subroutine that initializes the String in each nvtable element of the array:

Code: Select all

Sub InitNVTable(ByRef tbl() as nvtable, ByVal elemCnt as Integer)
	Dim i as byte
	For i = 1 to CByte(elemCnt)
		' set the string type for an allocated string
		Call RamPoke(&He0, tbl(i).s.DataAddress + 1)
	Next i
End Sub
Then, somewhere early in your code add this call:

Code: Select all

	Call InitNVTable(table1, UBound(table1))
We believe that we know how to correct this problem but we have not yet implemented and tested the prospective solution.
- Don Kinzer
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

We have implemented and preliminarily tested the solution to this problem. You may try out the pre-release build if you'd like.

You can use this version of the compiler with older versions of the IDE but to do so you'll have to disable the insertion into the .zxb of the compilation target information. The compiler option to do that is shown below; add it near the top of your .pjt file.

Code: Select all

--no-add-target
- Don Kinzer
Post Reply