Angus Salkeld napsal(a):
On Fri, Dec 09, 2011 at 05:24:06PM +0100, Jan Friesse wrote:
Hi (Angus), I found problem with map and libqb. Attached is simplest reproducer which I was able to create.
Result is following: Iter test.key1 = 0x5a2a290 (1) ... ==15090== For counts of detected and suppressed errors, rerun with: -v ==15090== ERROR SUMMARY: 2 errors from 1 contexts (suppressed: 6 from 6)
There should be NO invalid read of size ... Main problem seems to be with fact, that delete callback is called after free in iter, but in that time, pointer is already freed. Possible workaround may be to free value only in callback,
Free'ing in the callback is the expected usage (not the workaround) and there is a reason for it.
The iterator needs to reference count the node so that if someone else deletes it while you have it, it doesn't cause a problem.
I can understand technical reasons, but It's not documented.
What if you replace a value, you might leak memory. So we have a callback to allow you to free in both cases (delete and replace).
I know pointer before replace, so I can free it after replace with no problem.
but it can be very hard (impossible) to realize.
Why? Would it help to have a seperate callback to free mem?
It's simple. There is no documentation about iter/callback behavior and also, I can never be sure which callback will be called last. So ya, separate callback with semantic like "Now, I'm throwing away this pointer and I will no longer take evidence of that" seems to be perfect solution. Another solution may be documented behavior like "First/last registered callback is always called first/last", where preferred option is "First callback on NULL key with RECURSIVE event is always called last".
Honza
-Angus
...