Thread overview | ||||||
---|---|---|---|---|---|---|
|
April 05, 2014 Re: Manually-allocated memory and maximum array capacity | ||||
---|---|---|---|---|
| ||||
On 04/05/14 00:54, Joseph Rushton Wakeling wrote:
> Hello all,
>
> If we change the length of a dynamic array using the normal GC-based methods, e.g. by setting the array's .length property, we find that the array's capacity typically does not simply equal the length, but some greater value; there is excess allocation.
>
> Question: is there a comparable phenomenon for memory that is manually allocated using malloc? That is, that if we specify a particular number of bytes to allocate, it may be rounded up to a particular larger number?
>
> And, if so -- is there any way of guaranteeing what that larger number will be?
>
> The reason I ask is because, suppose that I use a dynamic array as a fixed-size buffer, and that its minimum size must be n. So, I can do:
>
> arr.length = n;
> if (arr.capacity > arr.length)
> {
> arr.length = arr.capacity;
> }
>
> ... and get the largest possible buffer that is at least size n, but does not allocate any more memory than setting length = n.
>
> I'm wondering if I can do something similar with manual memory allocation.
Not portably, as it will be libc and/or allocator specific.
For example, for glibc this would work:
/* static if (using_glibc) */
size_t capacity(const void* p) @property @safe {
return malloc_usable_size(p);
}
artur
|
April 07, 2014 Re: Manually-allocated memory and maximum array capacity | ||||
---|---|---|---|---|
| ||||
On 05/04/14 02:18, Artur Skawina wrote: > Not portably, as it will be libc and/or allocator specific. I think that's fine. I would be using it in circumstances where it's nice to have if I can get it, not a problem if I can't. As long as I make appropriate use of version statements to ensure it's only used where available, it should be OK and not affect usability. > For example, for glibc this would work: > > /* static if (using_glibc) */ > size_t capacity(const void* p) @property @safe { > return malloc_usable_size(p); > } Thanks! :-) |
April 08, 2014 Re: Manually-allocated memory and maximum array capacity | ||||
---|---|---|---|---|
| ||||
On 04/07/14 22:58, Joseph Rushton Wakeling wrote: > On 05/04/14 02:18, Artur Skawina wrote: >> Not portably, as it will be libc and/or allocator specific. > > I think that's fine. I would be using it in circumstances where it's nice to have if I can get it, not a problem if I can't. As long as I make appropriate use of version statements to ensure it's only used where available, it should be OK and not affect usability. > >> For example, for glibc this would work: >> >> /* static if (using_glibc) */ >> size_t capacity(const void* p) @property @safe { >> return malloc_usable_size(p); >> } > > Thanks! :-) Just be careful; I used the name 'capacity' because it fit into your example, but 'capacity' shouldn't be overloaded like that - it works very differently from the magic built-in property. The only safe way to use it would be: E[] aalloc(E)(size_t l) @trusted { if (l<size_t.max/E.sizeof) if (auto p = cast(E*)malloc(l*E.sizeof)) return p[0..malloc_usable_size(p)/E.sizeof]; return null; } artur |
April 08, 2014 Re: Manually-allocated memory and maximum array capacity | ||||
---|---|---|---|---|
| ||||
On 08/04/14 16:58, Artur Skawina wrote: > Just be careful; I used the name 'capacity' because it fit > into your example, but 'capacity' shouldn't be overloaded like > that - it works very differently from the magic built-in property. Yes, I was thinking that I'd better use a different name. (Actually the precise requirements are a bit different anyway, so there's no way to use it quite like that; but the principle is right.) > The only safe way to use it would be: > > E[] aalloc(E)(size_t l) @trusted { > if (l<size_t.max/E.sizeof) > if (auto p = cast(E*)malloc(l*E.sizeof)) > return p[0..malloc_usable_size(p)/E.sizeof]; > return null; > } Nicely done! :-) |
Copyright © 1999-2021 by the D Language Foundation