I have a crash when reading out a CString returned from a declare call.
[code]Dim p As Ptr = … // points to a CString
// This works
Dim mb As New Xojo.Core.MemoryBlock§
Dim cs1 As CString = mb.CStringValue(0)
// This crashes
Dim cs2 As CString = p.CString(0)[/code]
The crash log shows that the C standard library function strlen crashes. If I put a break point on the last line and then investigate the memory of mb and p, they are obviously both the same as they both show the same location in memory. A string followed by 0. So why does p.CString(0) crash the memory has not been freed or accessing p via the MemoryBlock wouldn’t work?
MemoryBlock.CString and Ptr.CString have different semantics. MemoryBlock’s returns a CString created by reading from the start until the first NUL or the end of the MemoryBlock. Ptr just dereferences memory and treats it as a CString (in C terminology, it’d be analogous to starting with a char**).
address value
1000 p // p As Ptr points to memory address 1012
1004 .
1008 .
1012 a // start of c string
1016 b
1020 c // end of c string
1024 \\0 // zero byte terminates the c string
1028 .
Now doing the following…
Dim cs As CString = p.CString(0)
… would as I thought read the c string at address 1012. As per the docs on Ptr:
[quote]You can convert the value referenced to by the pointer to a specific data type using the properties listed below.
…
CString(offset As Integer = 0) As CString
…[/quote]
But instead is seems to do this if I understand Joe correctly: Go to address 1012, read the value: 97 (small “a”) and treat it as a pointer, trying to read a non-existant c string at address 97.
That’s what’s happening. Set it up as a Ptr to a CString and the value is read correctly
[code] dim m As new MemoryBlock(100)
dim p As Ptr = m
m.Ptr(0) = Ptr(Integer(p) + 4) //put Ptr at 0 pointing to 4
m.CString(4) = “abc” //put CString at 4
dim s As CString = p.CString(0) //read Ptr.CString from 0
break[/code]
I don’t know the reason for this or the best way to work it. If there’s no given Ptr seems you’ll have to setup and manage some intermediary
[code] dim m As new MemoryBlock(100)
dim p As Ptr = m
m.CString(16) = “abc” //CString at 16 with no Ptr to
dim intermediaryMem As new MemoryBlock(4) //setup a separate
dim intermediaryPtr As Ptr = intermediaryMem //Ptr pointing
intermediaryPtr.Ptr(0) = Ptr( Integer(p) + 16 ) //to that 16
dim s As CString = intermediaryPtr.CString(0) //read