a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
90 lines
4.1 KiB
XML
90 lines
4.1 KiB
XML
<?xml version="1.0"?>
|
|
<clause number="25.8" title="Dynamic memory allocation">
|
|
<paragraph>Except for the stackalloc operator, C# provides no predefined constructs for managing non-garbage collected memory. Such services are typically provided by supporting class libraries or imported directly from the underlying operating system. <example>[Example: For example, the Memory class below illustrates how the heap functions of an underlying operating system might be accessed from C#: <code_example><![CDATA[
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
public unsafe class Memory
|
|
{
|
|
// Handle for the process heap. This handle is used in all calls to
|
|
the
|
|
// HeapXXX APIs in the methods below.
|
|
static int ph = GetProcessHeap();
|
|
// Private instance constructor to prevent instantiation.
|
|
private Memory() {}
|
|
// Allocates a memory block of the given size. The allocated memory is
|
|
// automatically initialized to zero.
|
|
public static void* Alloc(int size) {
|
|
void* result = HeapAlloc(ph, HEAP_ZERO_MEMORY, size);
|
|
if (result == null) throw new OutOfMemoryException();
|
|
return result;
|
|
}
|
|
// Copies count bytes from src to dst. The source and destination
|
|
// blocks are permitted to overlap.
|
|
public static void Copy(void* src, void* dst, int count) {
|
|
byte* ps = (byte*)src;
|
|
byte* pd = (byte*)dst;
|
|
if (ps > pd) {
|
|
for (; count != 0; count--) *pd++ = *ps++;
|
|
}
|
|
else if (ps < pd) {
|
|
for (ps += count, pd += count; count != 0; count--) *--pd = *--
|
|
ps;
|
|
}
|
|
}
|
|
// Frees a memory block.
|
|
public static void Free(void* block) {
|
|
if (!HeapFree(ph, 0, block)) throw new InvalidOperationException();
|
|
}
|
|
// Re-allocates a memory block. If the reallocation request is for a
|
|
// larger size, the additional region of memory is automatically
|
|
// initialized to zero.
|
|
public static void* ReAlloc(void* block, int size) {
|
|
void* result = HeapReAlloc(ph, HEAP_ZERO_MEMORY, block, size);
|
|
if (result == null) throw new OutOfMemoryException();
|
|
return result;
|
|
}
|
|
// Returns the size of a memory block.
|
|
public static int SizeOf(void* block) {
|
|
int result = HeapSize(ph, 0, block);
|
|
if (result == -1) throw new InvalidOperationException();
|
|
return result;
|
|
}
|
|
// Heap API flags
|
|
const int HEAP_ZERO_MEMORY = 0x00000008;
|
|
// Heap API functions
|
|
[DllImport("kernel32")]
|
|
static extern int GetProcessHeap();
|
|
[DllImport("kernel32")]
|
|
static extern void* HeapAlloc(int hHeap, int flags, int size);
|
|
[DllImport("kernel32")]
|
|
static extern bool HeapFree(int hHeap, int flags, void* block);
|
|
[DllImport("kernel32")]
|
|
static extern void* HeapReAlloc(int hHeap, int flags,
|
|
void* block, int size);
|
|
[DllImport("kernel32")]
|
|
static extern int HeapSize(int hHeap, int flags, void* block);
|
|
}
|
|
]]></code_example></example></paragraph>
|
|
<paragraph>
|
|
<example>An example that uses the Memory class is given below: <code_example><![CDATA[
|
|
class Test
|
|
{
|
|
static void Main() {
|
|
unsafe {
|
|
byte* buffer = (byte*)Memory.Alloc(256);
|
|
for (int i = 0; i < 256; i++) buffer[i] = (byte)i;
|
|
byte[] array = new byte[256];
|
|
fixed (byte* p = array) Memory.Copy(buffer, p, 256);
|
|
Memory.Free(buffer);
|
|
for (int i = 0; i < 256; i++) Console.WriteLine(array[i]);
|
|
}
|
|
}
|
|
}
|
|
]]></code_example></example>
|
|
</paragraph>
|
|
<paragraph>
|
|
<example>The example allocates 256 bytes of memory through Memory.Alloc and initializes the memory block with values increasing from 0 to 255. It then allocates a 256-element <keyword>byte</keyword> array and uses Memory.Copy to copy the contents of the memory block into the <keyword>byte</keyword> array. Finally, the memory block is freed using Memory.Free and the contents of the <keyword>byte</keyword> array are output on the console. end example]</example>
|
|
</paragraph>
|
|
<paragraph>End of conditionally normative text. </paragraph>
|
|
</clause>
|