开发者

nedmalloc: where does mem>=fm come from?

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜