GDI*_*512 2 c++ memory-management ada
我试图通过编写一组管理动态数组的过程来学习 Ada,但我不知道如何去做。在 C++ 中,我可以轻松地将任意对象放入内存中,如下所示:
#include <new>
#include <iostream>
class object {
private:
int value;
public:
~object() noexcept { std::cout << "<> "; }
object(int value) noexcept : value(value) { std::cout << object::value << ' '; }
};
constexpr auto size = 16;
int main() {
auto buffer = static_cast<object*>(::operator new(size * sizeof(object)));
for (auto offset = 0; offset < size; offset++)
new (buffer + offset) object(offset);
for (auto offset = 0; offset < size; offset++)
(buffer + offset)->~object();
::operator delete(buffer);
}
Run Code Online (Sandbox Code Playgroud)
Ada 中是否存在与此类“分配 x * sizeof(y) 并初始化 x y-items”操作等效的操作?
在 Ada 中,您可以编写自定义“存储池”(或子池),在其中重新定义分配函数以使用缓冲区。然后,您将访问类型“绑定”到存储池对象。
with System.Storage_Pools;
with System.Storage_Elements;
procedure Main is
type My_Storage_Pool is new System.Storage_Pools.Root_Storage_Pool with record
Buffer : System.Storage_Elements.Storage_Array (1 .. 1024);
Offset : System.Storage_Elements.Storage_Count := 1;
end record;
overriding procedure Allocate
(Self : in out My_Storage_Pool;
Address : out System.Address;
Size : System.Storage_Elements.Storage_Count;
Alignment : System.Storage_Elements.Storage_Count);
overriding procedure Deallocate
(Self : in out My_Storage_Pool;
Address : System.Address;
Size : System.Storage_Elements.Storage_Count;
Alignment : System.Storage_Elements.Storage_Count) is null;
overriding function Storage_Size
(Self : My_Storage_Pool)
return System.Storage_Elements.Storage_Count is (Self.Buffer'Length);
procedure Allocate
(Self : in out My_Storage_Pool;
Address : out System.Address;
Size : System.Storage_Elements.Storage_Count;
Alignment : System.Storage_Elements.Storage_Count)
is
use type System.Storage_Elements.Storage_Count;
begin
Address := Self.Buffer (Self.Offset)'Address;
Self.Offset := Self.Offset + Size;
end Allocate;
Pool : My_Storage_Pool;
type Object is null record;
type Object_Access is access Object with Storage_Pool => Pool;
X : Object_Access := new Object;
begin
null;
end Main;
Run Code Online (Sandbox Code Playgroud)
此外,对于未标记的类型,您可以使用Address子句将对象放置到给定地址。这个就简单多了。但这样对象初始化将不起作用,因此标记类型对象将无法获得虚拟表指针:
Buffer : Stream_Element_Array (1..1024);
Object : My_Object_Type
with Import, Address => Buffer (Offset)'Address;
-- Here Object'Tag is unassigned and dispatching won't work
Run Code Online (Sandbox Code Playgroud)