> You said Buffer was a local variable, but it's a parameter passed from the
> test.

>From the point of view of NetApiBufferFree, Buffer is a parameter,
which is equivalent to a local variable.  In C, all parameters are
pass-by-value.  You can simulate pass-by-reference by passing a
pointer, but it's still pass by (pointer) value.

> So, as far as I can see, the test does
>
> Buffer = HeapAlloc(GetProcessHeap(), NULL, 1024);
>
> HeapReAlloc(GetProcessHeap(),  0, Buffer, 1500);
>
> HeapFree(GetProcessHeap(), 0, Buffer);
> HeapFree(GetProcessHeap(), 0, Buffer);
>
> That's a double free, right? Valgrind is complaining about the second one.

Sort of.  I'll get back to your example in a second.  Valgrind rightly
complains about the second, double free.  I think that's what the test
was aiming to check:  whether a double free resulted in NERR_Success
being returned.  Whether that's a valid thing to check might be
debatable, but it does so, and I think the Valgrind warning is
appropriate.

My question is, why does assigning Buffer to NULL in the context of
NetApiBufferFree result in the warning going away?  Remember, the
first instance Buffer is different from the second.  If we label the
first stack frame with ' and the second with '', what we really have
is:

Buffer = HeapAlloc(GetProcessHeap(), NULL, 1024);

HeapReAlloc(GetProcessHeap(),  0, Buffer, 1500);

Buffer' = Buffer; /* A new copy of Buffer is created in the context of
NetApiBufferFree */
HeapFree(GetProcessHeap(), 0, Buffer');
Buffer'' = Buffer; /* A second copy of Buffer is created in the
context of NetApiBufferFree */
HeapFree(GetProcessHeap(), 0, Buffer'');

So setting Buffer' to NULL has no impact on the HeapFree of Buffer''.
The fact that this makes a Valgrind warning disappear still seems like
a Valgrind bug.  If it were doing static analysis, I'd say it's gotten
confused by aliasing.  Since it's doing dynamic analysis, I have to
ask why that's causing the warning to go away.
--Juan


Reply via email to