Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
135
Task/Memory-allocation/D/memory-allocation.d
Normal file
135
Task/Memory-allocation/D/memory-allocation.d
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
// D is a system language so its memory management is refined.
|
||||
// D supports thread-local memory on default, global memory, memory
|
||||
// allocated on the stack, the C heap, or the D heap managed by a
|
||||
// garbage collector, both manually and automatically.
|
||||
|
||||
// This program looks scary because its purpose is to show all the
|
||||
// variety. But lot of this stuff is only for special situations
|
||||
// (like alloca), and it's not necessary in most user code.
|
||||
|
||||
enum int nInts = 10; // Compile-time constant.
|
||||
|
||||
// This is thread-local:
|
||||
int[nInts] data1;
|
||||
|
||||
// This is global:
|
||||
__gshared int[nInts] data2;
|
||||
|
||||
void main() {
|
||||
// Static memory, it's thread-local but its name is usable
|
||||
// only locally:
|
||||
static int[nInts] data3;
|
||||
|
||||
// Static memory, it's global but its name is usable only locally:
|
||||
__gshared static int[nInts] data4;
|
||||
|
||||
// ----------------------
|
||||
// D supports the functions that manage memory of the C heap:
|
||||
import core.stdc.stdlib: malloc, calloc, realloc, free, alloca;
|
||||
|
||||
// Allocates space for some integers on the heap,
|
||||
// the memory is not initialized:
|
||||
auto ptr1 = cast(int*)malloc(nInts * int.sizeof);
|
||||
if (ptr1 == null)
|
||||
return;
|
||||
|
||||
// Increases the space for one more integer, the new space
|
||||
// is not initialized, but the old space is not modified:
|
||||
ptr1 = cast(int*)realloc(ptr1, (nInts + 1) * int.sizeof);
|
||||
if (ptr1 == null)
|
||||
return;
|
||||
|
||||
// calloc allocates on the heap and zeros the memory:
|
||||
auto ptr2 = cast(int*)calloc(nInts, int.sizeof);
|
||||
if (ptr2 == null)
|
||||
return;
|
||||
|
||||
// You can create a slice from a pointer:
|
||||
auto slice1 = ptr2[0 .. nInts];
|
||||
|
||||
// Frees the memory:
|
||||
free(ptr2);
|
||||
free(ptr1);
|
||||
|
||||
// ----------------------
|
||||
import core.stdc.stdio: puts;
|
||||
|
||||
static struct Test {
|
||||
~this() { puts("Test destructor"); }
|
||||
}
|
||||
|
||||
// Memory allocated on the stack:
|
||||
Test[2] array1;
|
||||
|
||||
{
|
||||
// More memory allocated on the stack:
|
||||
Test[2] array2;
|
||||
// Here array2 is removed from the stack,
|
||||
// and all array2 destructors get called.
|
||||
}
|
||||
puts("Block end.");
|
||||
|
||||
// alloca is supported in D. It's similar to malloc but the
|
||||
// memory is allocated on the stack:
|
||||
int* ptr3 = cast(int*)alloca(nInts * int.sizeof);
|
||||
|
||||
// You can create a slice from the pointer:
|
||||
auto slice2 = ptr3[0 .. nInts];
|
||||
|
||||
// Do not free the memory allocated with alloca:
|
||||
// free(ptr3);
|
||||
|
||||
// ----------------------
|
||||
// Allocates a dynamic array on the D heap managed by
|
||||
// the D garbage collector:
|
||||
auto array3 = new int[nInts];
|
||||
|
||||
// Try to reserve capacity for a dynamic array on the D heap:
|
||||
int[] array4;
|
||||
array4.reserve(nInts);
|
||||
assert(array4.capacity >= nInts);
|
||||
assert(array4.length == 0);
|
||||
|
||||
// Appends one integer to the dynamic array:
|
||||
array4 ~= 100;
|
||||
|
||||
// Assume that it is safe to append to this array. Appends made
|
||||
// to this array after calling this function may append in place,
|
||||
// even if the array was a slice of a larger array to begin with:
|
||||
array4.assumeSafeAppend;
|
||||
array4 ~= 200;
|
||||
array4 ~= 300;
|
||||
assert(array4.length == 3);
|
||||
// See here for more info:
|
||||
// http://dlang.org/d-array-article.html
|
||||
|
||||
|
||||
// Allocates a struct and a class on the D GC heap:
|
||||
static class Foo { int x; }
|
||||
Test* t = new Test; // This destructor will not be called.
|
||||
Foo f1 = new Foo; // f1 is a class reference.
|
||||
|
||||
// Optional. Destroys the given object and puts it in
|
||||
// an invalid state:
|
||||
f1.destroy;
|
||||
|
||||
import std.typecons: scoped;
|
||||
|
||||
// Allocates a class on the stack, unsafe:
|
||||
auto f3 = scoped!Foo();
|
||||
|
||||
// ----------------------
|
||||
import core.memory: GC;
|
||||
|
||||
// Allocates an aligned block from the GC, initialized to zero.
|
||||
// Plus it doesn't scan through this block on collect.
|
||||
auto ptr4 = cast(int*)GC.calloc(nInts * int.sizeof,
|
||||
GC.BlkAttr.NO_SCAN);
|
||||
|
||||
// No need to test for this, because GC.calloc usually
|
||||
// throws OutOfMemoryError if it can't allocate.
|
||||
// if (ptr4 == null)
|
||||
// exit(1);
|
||||
|
||||
GC.free(ptr4); // This is optional.
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue