While implementing nedmalloc into my application, I am frequently hitting a situation when nedmalloc refuses to free a block of memory, claiming it did not allocate it.
I am using v1.06beta1_svn1151 version.
While debugging I have come up to the point I see a particular condition which is failing, all other (including magic numbers) succeed. The condition is this:
if((size_t)mem-(size_t)fm>=(size_t)1<<(SIZE_T_BITSIZE-1)) return 0;
On Win32 th开发者_如何学编程is seems to be equivalent to:
if((int)((size_t)mem-(size_t)fm)<0) return 0;
Which seems to be the same as:
if((size_t)mem<(size_t)fm) return 0;
In my case I really see mem < fm. What I do not understand now is, where does this condition come from. I cannot find anything which would guarantee the fm <= m anywhere in code. Yet, "select isn't broken": I doubt it would really be a bug in nedmalloc, most likely I am doing something wrong somewhere, but I cannot find it. Once I turn debugging features of nedmalloc on, the problem goes away.
If someone here understands inner working of nedmalloc, could you please explain to me why is fm <= mem guaranteed?
I can see now for this line there was added a comment /* See if mem is lower in memory than mem */ and it was disabled using #if 0 in beta svn1159. The condition is not mature and it is probably wrong (it is still left in the Linux specific part of the code - most likely wrong there as well?)
Lesson learned: "beta select can be broken".
I am assuming that SIZE_T_BITSIZE
is the number of bits in size_t
type, so shifting 1 by SIZE_T_BITSIZE - 1
will give you (SIZE_MAX + 1) / 2
(mathematical) value. So the condition is testing if (size_t)mem - (size_t)fm
is greater than or equal to the mathematical value of (SIZE_MAX + 1) / 2
.
This is not the same as (int)((size_t)mem - (size_t)fm) < 0
. Further, if mem
and/or fm
are cast to size_t
, which is an unsigned type, the arithmetic happens in unsigned types, which means that the difference cannot be less than 0. So, even if (size_t)mem
is less than (size_t)fm
, (size_t)mem - (size_t)fm
is never going to be less than 0. It is equal to the difference mem - fm
plus SIZE_MAX
plus 1
, which is a positive value. Converting that value to an int
may overflow, which is implementation-defined, or may not overflow, in which case you end up with a positive value.
So, to answer your question, if (size_t)mem
is less than (size_t)fm
, you probably have a bug before that point.
What is m
? By m
, do you mean mem
?
Edit: Looks like a bug in nedmalloc
, for reasons I mentioned above. The code in question has been commented out in the latest version.
精彩评论