You are not logged in.
Pages: 1
Hello,
Using Delphi 10.3.2, targeting Win32 executable.
I have demo code at https://pastebin.com/wqdBqRmT
When I run it I get access violation in SynCommons.pas:55273
D^ := P^; // 3 stages pipelined process of unescaped chars
Synopse commit version is: 1.18.5037
I get same error at same line (line no 54907 this time) using latest codes on GitHub, too. That code Synopse commit version is: 1.18.5448
I am not sure if it is me doing something wrong. I know that I can successfully de-serialize identical json string using an alternative record based library. I do want to use mORMot.
So, I am posting here to see if there is anything to check in mORMot.
Any help is appreciated.
Thanks & regards,
Ertan
Last edited by ertank (2019-11-06 15:16:27)
Offline
Very nice demo!
Instead of :
Pointer(LJson)
try
@LJson[1]
Best regards!
Offline
It works as suggested.
Interesting. I have legacy code about 3 years old working just fine using Pointer() with earlier versions of mORMot:
DynArrayLoadJSON(Taxes, Pointer(sRaw), TypeInfo(TStTaxRatesString));
I cannot say I am good at pointers. I wonder why one works and not the other?
Offline
If you look at SynSelfTests (part of TestSQL3 project) you will see Pointer() is used all over the place including with DynArrayLoadJSON, and that seems to work just fine so I guess there's a specific compiler directive that enables such type casting.
Personally I prefer the more explicit approach.
Last edited by pvn0 (2019-11-07 09:26:58)
Offline
Ok, never mind about compiler directive, the reason your demo fails is because in your case, LJson is not actually a unique string.
See https://pastebin.com/TLTZkDap
Once LJson is made a unique string with ref count >=1, then such pointer type casting will work but I don't recommend it.
Better to use UniqueRawUTF8(LJson) instead of Pointer(LJson) or directly @LJson[1] if you don't care about FPC compatibility.
Last edited by pvn0 (2019-11-07 11:20:35)
Offline
This is as expected.
You are missing one point: your string is in read/only memory.
Whereas in the TestSQL3.dpr project, it uses pointer() for read/write strings in memory - strings which have been allocated from the heap.
In your code:
LJson := JsonToDeserialize;
put a reference to a read-only constant string - with refcount = -1.
This is what the compiler does for constants: no memory copy nor heap allocation, just reference of its own read-only binary.
And DynArrayLoadJson() modifies the buffer in-place (adding #0 when needed).
So it tried to write some read-only memory - and the Access Violation appears.
By calling UniqueRawUTF8(LJson), you will ensure that the LJson string is read/write.
Offline
I have just make it more obvious in the comments/documentation.
And introduced a new overloaded DynArrayLoadJSON() function which will make a copy of the input buffer.
See https://synopse.info/fossil/info/bd63059e2f
Offline
I have just make it more obvious in the comments/documentation.
And introduced a new overloaded DynArrayLoadJSON() function which will make a copy of the input buffer.
See https://synopse.info/fossil/info/bd63059e2f
I like new overload function more because of its Boolean return makes it easier to understand if result is a success or not.
Thank you.
Offline
Pages: 1