Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
C-sharp language specification.2004.pdf
Скачиваний:
14
Добавлен:
23.08.2013
Размер:
2.55 Mб
Скачать

Chapter 25 Unsafe code

1a stackalloc initializer is used in the IntToString method to allocate a buffer of 16 characters on the

2stack. The buffer is automatically discarded when the method returns. end example]

325.8 Dynamic memory allocation

4Except for the stackalloc operator, C# provides no predefined constructs for managing non-garbage

5collected memory. Such services are typically provided by supporting class libraries or imported directly

6from the underlying operating system. [Example: The Memory static class below illustrates how the heap

7functions of an underlying operating system might be accessed from C#:

8using System;

9using System.Runtime.InteropServices;

10public unsafe static class Memory

11{

12

// Handle for the process heap. This handle is used in all calls to

13

// the HeapXXX APIs in the methods below.

14

static int ph = GetProcessHeap();

15

// Allocates a memory block of the given size. The allocated memory is

16

// automatically initialized to zero.

17

public static void* Alloc(int size) {

18

void* result = HeapAlloc(ph, HEAP_ZERO_MEMORY, size);

19

if (result == null) throw new OutOfMemoryException();

20

return result;

21

}

22

// Copies count bytes from src to dst. The source and destination

23

// blocks are permitted to overlap.

24

public static void Copy(void* src, void* dst, int count) {

25

byte* ps = (byte*)src;

26

byte* pd = (byte*)dst;

27

if (ps > pd) {

28

for (; count != 0; count--) *pd++ = *ps++;

29

}

30

else if (ps < pd) {

31

for (ps += count, pd += count; count != 0; count--)

32

*--pd = *--ps;

33

}

34

}

35

// Frees a memory block.

36

public static void Free(void* block) {

37

if (!HeapFree(ph, 0, block)) throw new InvalidOperationException();

38

}

39

// Re-allocates a memory block. If the reallocation request is for a

40

// larger size, the additional region of memory is automatically

41

// initialized to zero.

42

public static void* ReAlloc(void* block, int size) {

43

void* result = HeapReAlloc(ph, HEAP_ZERO_MEMORY, block, size);

44

if (result == null) throw new OutOfMemoryException();

45

return result;

46

}

47

// Returns the size of a memory block.

48

public static int SizeOf(void* block) {

49

int result = HeapSize(ph, 0, block);

50

if (result == -1) throw new InvalidOperationException();

51

return result;

52

}

53

// Heap API flags

54

const int HEAP_ZERO_MEMORY = 0x00000008;

55

// Heap API functions

395

 

C# LANGUAGE SPECIFICATION

1

[DllImport("kernel32")]

2

static extern int GetProcessHeap();

3

[DllImport("kernel32")]

4

static extern void* HeapAlloc(int hHeap, int flags, int size);

5

[DllImport("kernel32")]

6

static extern bool HeapFree(int hHeap, int flags, void* block);

7

[DllImport("kernel32")]

8

static extern void* HeapReAlloc(int hHeap, int flags,

9

void* block, int size);

10 [DllImport("kernel32")]

11static extern int HeapSize(int hHeap, int flags, void* block);

12}

13An example that uses the Memory class is given below:

14class Test

15{

16

static void Main() {

17

unsafe {

18

byte* buffer = (byte*)Memory.Alloc(256);

19

for (int i = 0; i < 256; i++) buffer[i] = (byte)i;

20

byte[] array = new byte[256];

21

fixed (byte* p = array) Memory.Copy(buffer, p, 256);

22

Memory.Free(buffer);

23

for (int i = 0; i < 256; i++) Console.WriteLine(array[i]);

24

}

25}

26}

27The example allocates 256 bytes of memory through Memory.Alloc and initializes the memory block with

28values increasing from 0 to 255. It then allocates a 256-element byte array and uses Memory.Copy to copy

29the contents of the memory block into the byte array. Finally, the memory block is freed using

30Memory.Free and the contents of the byte array are output on the console. end example]

31End of conditionally normative text.

396

Соседние файлы в предмете Электротехника