digitalmars.D.learn - std.expreimantal.allocator deallocate
- vitamin (37/37) Jan 24 2021 Allocators from std.expreimantal.allocator allocate memory and
- Paul Backus (4/6) Jan 24 2021 It depends on the specific allocator, but in general, it is only
- vitamin (6/12) Jan 24 2021 thanks,
- Petar Kirov [ZombineDev] (25/39) Jan 24 2021 Yes, it is guaranteed [0]. Even though some allocator
- Petar Kirov [ZombineDev] (13/19) Jan 24 2021 To add to that, if an allocator defines `resolveInternalPointer`
- vitamin (3/18) Jan 25 2021 Thanks
- Jacob Carlborg (8/14) Jan 25 2021 You can get the dynamic size of an object using
- vitamin (5/19) Jan 25 2021 I implementing ref counted pointer with support for weak
Allocators from std.expreimantal.allocator allocate memory and return slice void[] to allocated memory. Method deallocate has as parameter void[] slice to allocated memory. It is Ok when I call deallocate with smaller slice or I need track exact lengtht? Example: import std.experimental.allocator : theAllocator; import core.lifetime : emplace; import std.stdio; class Base{ int i; } class Derived : Base{ int j; } Base make(){ void[] x = theAllocator.allocate(__traits(classInstanceSize, Derived)); writeln("allocate: ", x.length); emplace!Derived(x); return cast(Derived)x.ptr; } void destruct(Base base){ void[] x = (cast(void*)base)[0 .. __traits(classInstanceSize, Base)]; writeln("deallocate: ", x.length); theAllocator.deallocate(x); } void main(){ Base x = make; scope(exit)destruct(x); ///some code... } //print: //allocate: 24 //deallocate: 20
Jan 24 2021
On Sunday, 24 January 2021 at 11:00:17 UTC, vitamin wrote:It is Ok when I call deallocate with smaller slice or I need track exact lengtht?It depends on the specific allocator, but in general, it is only guaranteed to work correctly if the slice you pass to deallocate is exactly the same as the one you got from allocate.
Jan 24 2021
On Sunday, 24 January 2021 at 14:56:25 UTC, Paul Backus wrote:On Sunday, 24 January 2021 at 11:00:17 UTC, vitamin wrote:thanks, is guaranteed this: void[] data = Allocator.allocate(data_size); assert(data.length == data_size) or can be data.length >= data_size ?It is Ok when I call deallocate with smaller slice or I need track exact lengtht?It depends on the specific allocator, but in general, it is only guaranteed to work correctly if the slice you pass to deallocate is exactly the same as the one you got from allocate.
Jan 24 2021
On Sunday, 24 January 2021 at 16:16:12 UTC, vitamin wrote:On Sunday, 24 January 2021 at 14:56:25 UTC, Paul Backus wrote:Yes, it is guaranteed [0]. Even though some allocator implementations will allocate a larger block internally to back your requested allocation size, `allocate` [1] must return the same number of bytes as you requested, or a `null` slice. If an allocator has a non-trivial `goodAllocSize(s)` [2] function (i.e. one that is not the identity function `s => s`) and you you allocate say N bytes, while allocator.goodAllocSize(N) returns M, M > N, it means that most likely calling `expand` [3] will succeed - meaning it will give you the excess memory that it has internally for free. I say "most likely", because this is the intention of the allocator building blocks spec, even though it's not specified. In theory, `expand` could fail in such situation either because of an allocator implementation deficiency (which would technically not be a bug), or because `allocate` was called concurrently by another thread and the allocator decided to give the excess space to someone else. [0]: https://dlang.org/phobos/std_experimental_allocator_building_blocks.html [1]: https://dlang.org/phobos/std_experimental_allocator.html#.IAllocator.allocate [2]: https://dlang.org/phobos/std_experimental_allocator.html#.IAllocator.goodAllocSize [3]: https://dlang.org/phobos/std_experimental_allocator.html#.IAllocator.expandOn Sunday, 24 January 2021 at 11:00:17 UTC, vitamin wrote:thanks, is guaranteed this: void[] data = Allocator.allocate(data_size); assert(data.length == data_size) or can be data.length >= data_size ?It is Ok when I call deallocate with smaller slice or I need track exact lengtht?It depends on the specific allocator, but in general, it is only guaranteed to work correctly if the slice you pass to deallocate is exactly the same as the one you got from allocate.
Jan 24 2021
On Sunday, 24 January 2021 at 14:56:25 UTC, Paul Backus wrote:On Sunday, 24 January 2021 at 11:00:17 UTC, vitamin wrote:To add to that, if an allocator defines `resolveInternalPointer` [0][1] you could be able to get the original slice that was allocated (and then pass that to `deallocate`, but not all allocators define `resolveInternalPointer` and also even if they do define it, they're not required to maintain complete book-keeping as doing so could have bad performance implications (i.e. calling say `a.resolveInternalPointer(a.allocate(10)[3 .. 6].ptr, result)` can return `Ternary.unknown`. [0]: https://dlang.org/phobos/std_experimental_allocator.html#.IAllocator.resolveInternalPointer [1]: https://dlang.org/phobos/std_experimental_allocator_building_blocks.htmlIt is Ok when I call deallocate with smaller slice or I need track exact lengtht?It depends on the specific allocator, but in general, it is only guaranteed to work correctly if the slice you pass to deallocate is exactly the same as the one you got from allocate.
Jan 24 2021
On Sunday, 24 January 2021 at 18:38:42 UTC, Petar Kirov [ZombineDev] wrote:On Sunday, 24 January 2021 at 14:56:25 UTC, Paul Backus wrote:Thanks[...]To add to that, if an allocator defines `resolveInternalPointer` [0][1] you could be able to get the original slice that was allocated (and then pass that to `deallocate`, but not all allocators define `resolveInternalPointer` and also even if they do define it, they're not required to maintain complete book-keeping as doing so could have bad performance implications (i.e. calling say `a.resolveInternalPointer(a.allocate(10)[3 .. 6].ptr, result)` can return `Ternary.unknown`. [0]: https://dlang.org/phobos/std_experimental_allocator.html#.IAllocator.resolveInternalPointer [1]: https://dlang.org/phobos/std_experimental_allocator_building_blocks.html
Jan 25 2021
On Sunday, 24 January 2021 at 11:00:17 UTC, vitamin wrote:void destruct(Base base){ void[] x = (cast(void*)base)[0 .. __traits(classInstanceSize, Base)]; writeln("deallocate: ", x.length); theAllocator.deallocate(x); }You can get the dynamic size of an object using `typeid(base).initializer.length`. Base base = new Derived; assert(__traits(classInstanceSize, Derived) == typeid(base).initializer.length); -- /Jacob Carlborg
Jan 25 2021
On Monday, 25 January 2021 at 10:28:11 UTC, Jacob Carlborg wrote:On Sunday, 24 January 2021 at 11:00:17 UTC, vitamin wrote:I implementing ref counted pointer with support for weak pointers. Problem was that expired weak pointer can point to already destroyed data => typeid() no longer work or ref type is extern(C) class => typeid() doesn't work.void destruct(Base base){ void[] x = (cast(void*)base)[0 .. __traits(classInstanceSize, Base)]; writeln("deallocate: ", x.length); theAllocator.deallocate(x); }You can get the dynamic size of an object using `typeid(base).initializer.length`. Base base = new Derived; assert(__traits(classInstanceSize, Derived) == typeid(base).initializer.length); -- /Jacob Carlborg
Jan 25 2021