|
From: Geoffrey I. <ir...@na...> - 2012-07-26 16:14:41
Attachments:
error.txt
|
I'm using valgrind 3.8.0.SVN from MacPorts on Mac OS X 10.7.4.
valgrind is showing a memory leak of 18 bytes when I try to allocate
an empty array using posix_memalign. The leak warning is attached.
The posix_memalign call is
void* data;
const size_t alignment = max(sizeof(T),sizeof(void*));
if (posix_memalign(&data,alignment,sizeof(T)*size))
throw bad_alloc();
where sizeof(T)==64 and size==0. I've confirmed that I call free on
the same pointer. If I replace the code with
void* data = malloc(sizeof(T)*size);
the leak warning goes away. Any idea what could be going wrong?
Thanks,
Geoffrey
|
|
From: Geoffrey I. <ir...@na...> - 2012-07-26 16:38:38
|
On Thu, Jul 26, 2012 at 9:14 AM, Geoffrey Irving <ir...@na...> wrote:
> I'm using valgrind 3.8.0.SVN from MacPorts on Mac OS X 10.7.4.
> valgrind is showing a memory leak of 18 bytes when I try to allocate
> an empty array using posix_memalign. The leak warning is attached.
>
> The posix_memalign call is
>
> void* data;
> const size_t alignment = max(sizeof(T),sizeof(void*));
> if (posix_memalign(&data,alignment,sizeof(T)*size))
> throw bad_alloc();
>
> where sizeof(T)==64 and size==0. I've confirmed that I call free on
> the same pointer. If I replace the code with
>
> void* data = malloc(sizeof(T)*size);
>
> the leak warning goes away. Any idea what could be going wrong?
Okay, this looks like a bug in Mac's posix_memalign, not a valgrind
issue. Here's a reduced test program:
#include <stdlib.h>
#include <stdio.h>
int main() {
void* data = 0;
int r = posix_memalign(&data,64,0);
printf("r = %d, data = %p\n",r,data);
free(data);
return 0;
}
Running this produces
tile:scratch% ./memalign
r = 0, data = 0x106900840
memalign(3949) malloc: *** error for object 0x106900840: pointer
being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
Allocating 64 bytes instead of 0 works fine. I'll tell Apple about it
and add the !size check to my code.
Thanks,
Geoffrey
|
|
From: John R. <jr...@bi...> - 2012-07-26 17:27:38
|
>> I'm using valgrind 3.8.0.SVN from MacPorts on Mac OS X 10.7.4. >> valgrind is showing a memory leak of 18 bytes when I try to allocate >> an empty array using posix_memalign. The leak warning is attached. >> >> The posix_memalign call is >> >> void* data; >> const size_t alignment = max(sizeof(T),sizeof(void*)); >> if (posix_memalign(&data,alignment,sizeof(T)*size)) >> throw bad_alloc(); >> >> where sizeof(T)==64 and size==0. I've confirmed that I call free on >> the same pointer. If I replace the code with >> >> void* data = malloc(sizeof(T)*size); >> >> the leak warning goes away. Any idea what could be going wrong? There is a dispute about the meaning of memory allocation when the requested size is 0. The recipient must not access any memory there; after all, the requested size is zero. Also, NULL strings occur *everywhere*, so *any* address ought to be satisfactory for a zero-length block. However, some users were in the habit of using malloc(0) as an implementation of the LISP (gensym). The standard grudgingly accommodated those users. That was a mistake. The result is that most implementations allocate 1 byte when you ask for zero. -- |
|
From: Paul F. <pa...@fr...> - 2012-07-26 20:10:24
|
John Reiser wrote: > There is a dispute about the meaning of memory allocation when > the requested size is 0. The recipient must not access any memory > there; after all, the requested size is zero. Also, NULL strings > occur *everywhere*, so *any* address ought to be satisfactory > for a zero-length block. In C++, operator new[] with a size of zero is well defined. It should return a valid pointar that should not be dereferenced. A+ Paul |
|
From: Geoffrey I. <ir...@na...> - 2012-07-26 17:43:07
|
On Thu, Jul 26, 2012 at 10:28 AM, John Reiser <jr...@bi...> wrote: >>> I'm using valgrind 3.8.0.SVN from MacPorts on Mac OS X 10.7.4. >>> valgrind is showing a memory leak of 18 bytes when I try to allocate >>> an empty array using posix_memalign. The leak warning is attached. >>> >>> The posix_memalign call is >>> >>> void* data; >>> const size_t alignment = max(sizeof(T),sizeof(void*)); >>> if (posix_memalign(&data,alignment,sizeof(T)*size)) >>> throw bad_alloc(); >>> >>> where sizeof(T)==64 and size==0. I've confirmed that I call free on >>> the same pointer. If I replace the code with >>> >>> void* data = malloc(sizeof(T)*size); >>> >>> the leak warning goes away. Any idea what could be going wrong? > > There is a dispute about the meaning of memory allocation when > the requested size is 0. The recipient must not access any memory > there; after all, the requested size is zero. Also, NULL strings > occur *everywhere*, so *any* address ought to be satisfactory > for a zero-length block. > > However, some users were in the habit of using malloc(0) as an > implementation of the LISP (gensym). The standard grudgingly > accommodated those users. That was a mistake. The result is > that most implementations allocate 1 byte when you ask for zero. Wow, that's suitably insane. Though I suppose it's related to the C/C++ ban on zero size structs and no two structs sharing the same memory address. This is still a bug in Mac's posix_memalloc, though, since presumably any craziness they decide to return should still be a valid argument to free. I filed a bug with Apple and worked around it in my code with a !size check. Geoffrey |
|
From: Sean M. <se...@ro...> - 2012-07-26 18:12:50
|
On Thu, 26 Jul 2012 10:42:41 -0700, Geoffrey Irving said: >This is still a bug in Mac's posix_memalloc, though, since presumably >any craziness they decide to return should still be a valid argument >to free. I filed a bug with Apple and worked around it in my code >with a !size check. What's your bug number? I think it's definitely worth a bug report. If nothing else, the man page should discuss whether a zero size is undefined behaviour or not. Also, here's a reference about 0-sized allocs: <https://www.securecoding.cert.org/confluence/display/seccode/MEM04-C.+Do+not+perform+zero+length+allocations> -- ____________________________________________________________ Sean McBride, B. Eng se...@ro... Rogue Research www.rogue-research.com Mac Software Developer Montréal, Québec, Canada |
|
From: Patrick J. L. <lop...@gm...> - 2012-07-26 20:57:54
|
On Thu, Jul 26, 2012 at 11:12 AM, Sean McBride <se...@ro...> wrote: > > I think it's definitely worth a bug report. If nothing else, the man page should discuss whether a zero size is undefined behaviour or not. The POSIX spec makes it pretty clear that this is not undefined behavior: http://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_memalign.html "If the size of the space requested is 0, the behavior is implementation-defined; the value returned in memptr shall be either a null pointer or a unique pointer." and "The free() function shall deallocate memory that has previously been allocated by posix_memalign()." Geoffrey is right; this is unambiguously a bug in Apple's C library. Nice catch. - Pat |
|
From: Geoffrey I. <ir...@na...> - 2012-07-26 18:24:24
|
On Thu, Jul 26, 2012 at 11:12 AM, Sean McBride <se...@ro...> wrote: > On Thu, 26 Jul 2012 10:42:41 -0700, Geoffrey Irving said: > >>This is still a bug in Mac's posix_memalloc, though, since presumably >>any craziness they decide to return should still be a valid argument >>to free. I filed a bug with Apple and worked around it in my code >>with a !size check. > > What's your bug number? It's 11965329 filed through https://bugreport.apple.com, but I don't know how to produce a publically accessible link. Thus, as far as I know, the number is only useful to me and Apple. Is there a better place to put such reports? > I think it's definitely worth a bug report. If nothing else, the man page should discuss whether a zero size is undefined behaviour or not. > > Also, here's a reference about 0-sized allocs: > <https://www.securecoding.cert.org/confluence/display/seccode/MEM04-C.+Do+not+perform+zero+length+allocations> Thanks for the link. I'll fix a few other places in my code to check for this. Geoffrey |
|
From: Sean M. <se...@ro...> - 2012-07-26 21:45:51
|
On Thu, 26 Jul 2012 11:24:02 -0700, Geoffrey Irving said: >It's 11965329 filed through https://bugreport.apple.com, but I don't >know how to produce a publically accessible link. You can't. >Thus, as far as I >know, the number is only useful to me and Apple. Mostly. Though when I file my bug, I can mention yours, so they can relate them. >Is there a better >place to put such reports? You can here: <http://openradar.appspot.com/> >Thanks for the link. I'll fix a few other places in my code to check >for this. The clang static analyzer can detect some instances, but of course only if it's known to be 0 at compiler-time. -- ____________________________________________________________ Sean McBride, B. Eng se...@ro... Rogue Research www.rogue-research.com Mac Software Developer Montréal, Québec, Canada |