views:

105

answers:

2

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 this 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?

+1  A: 

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.

Alok
I am assuming Win32 (as indicated by a tag).
Suma
Yes, m should be mem. Thanks for pointing out, this is corrected now.
Suma
@Suma, see my edit.
Alok
+1  A: 

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".

Suma
Haha, yeah, after you updated your post to include that you are using an svn version, and I noticed that the line you mention is not in the current stable version, I was beginning to doubt select as well... :)
Thomas
What to do with this now? The whole question point seems to be moot now - it does not seem to me StackOverflow should document already fixed bugs in various libs. I guess I will probably vote to delete this question? (Still, I am very glad to have asked it - your question about which version helped me a lot).
Suma