Memory allocation: Difference between revisions
Content added Content deleted
Puppydrum64 (talk | contribs) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 8: | Line 8: | ||
=={{header|360 Assembly}}== |
=={{header|360 Assembly}}== |
||
< |
<syntaxhighlight lang="360 assembly"> |
||
* Request to Get Storage Managed by "GETMAIN" Supervisor Call (SVC 4) |
* Request to Get Storage Managed by "GETMAIN" Supervisor Call (SVC 4) |
||
LA 1,PLIST Point Reg 1 to GETMAIN/FREEMAIN Parm List |
LA 1,PLIST Point Reg 1 to GETMAIN/FREEMAIN Parm List |
||
Line 31: | Line 31: | ||
DC A(STG@) Pointer to Address of Storage Area |
DC A(STG@) Pointer to Address of Storage Area |
||
DC X'0000' (Unconditional Request; Subpool 0) |
DC X'0000' (Unconditional Request; Subpool 0) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Example below shows de facto modern day use of HLASM techniques: |
Example below shows de facto modern day use of HLASM techniques: |
||
Line 39: | Line 39: | ||
* The code shows the use of the system supplied linkage stack to save caller's registers (BAKR) and restore them on return (PR), as opposed to STM/LM of the caller's register contents. |
* The code shows the use of the system supplied linkage stack to save caller's registers (BAKR) and restore them on return (PR), as opposed to STM/LM of the caller's register contents. |
||
* Finally, the code is REENTRANT, meaning it could be loaded in a system module directory (LINKLIST, LPA), and executed simultaneously by multiple callers. Though not a requirement for this type of sample code it is a best practice in assembler coding. |
* Finally, the code is REENTRANT, meaning it could be loaded in a system module directory (LINKLIST, LPA), and executed simultaneously by multiple callers. Though not a requirement for this type of sample code it is a best practice in assembler coding. |
||
<syntaxhighlight lang="360 assembly"> |
|||
<lang 360 Assembly> |
|||
STOREXNO AMODE 31 |
STOREXNO AMODE 31 |
||
STOREXNO RMODE ANY |
STOREXNO RMODE ANY |
||
Line 73: | Line 73: | ||
WALEN EQU *-DYNAREA length of obtained area |
WALEN EQU *-DYNAREA length of obtained area |
||
END STOREXNO end of module |
END STOREXNO end of module |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|6502 Assembly}}== |
=={{header|6502 Assembly}}== |
||
Line 79: | Line 79: | ||
The "heap" can be considered the zero page, or any other section of RAM that the hardware allows for general access. Anything besides the zero page is platform-specific. Accessing the heap is as simple as storing values in a specified address. |
The "heap" can be considered the zero page, or any other section of RAM that the hardware allows for general access. Anything besides the zero page is platform-specific. Accessing the heap is as simple as storing values in a specified address. |
||
< |
<syntaxhighlight lang="6502asm">LDA #$FF ;load 255 into the accumulator |
||
STA $00 ;store at zero page memory address $00 |
STA $00 ;store at zero page memory address $00 |
||
STA $0400 ;store at absolute memory address $0400</ |
STA $0400 ;store at absolute memory address $0400</syntaxhighlight> |
||
A byte can be stored to the stack with <code>PHA</code> and retrieved with <code>PLA</code>. Later revisions of the 6502 allowed the X and Y registers to be directly pushed/popped with <code>PHX</code>, <code>PHY</code>, <code>PLX</code>, and <code>PLY</code>. The original 6502 could only access the stack through the accumulator. |
A byte can be stored to the stack with <code>PHA</code> and retrieved with <code>PLA</code>. Later revisions of the 6502 allowed the X and Y registers to be directly pushed/popped with <code>PHX</code>, <code>PHY</code>, <code>PLX</code>, and <code>PLY</code>. The original 6502 could only access the stack through the accumulator. |
||
Line 89: | Line 89: | ||
=={{header|68000 Assembly}}== |
=={{header|68000 Assembly}}== |
||
The <code>LINK</code> and <code>UNLK</code> instructions are designed to create [[C]]-style stack frames. The operands of the <code>LINK</code> instruction are an address register (other than A7) and a displacement (must be even and either 0 or negative.) |
The <code>LINK</code> and <code>UNLK</code> instructions are designed to create [[C]]-style stack frames. The operands of the <code>LINK</code> instruction are an address register (other than A7) and a displacement (must be even and either 0 or negative.) |
||
< |
<syntaxhighlight lang="68000devpac">MyFunction: |
||
LINK A6,#-16 ;create a stack frame of 16 bytes. Now you can safely write to (SP+0) thru (SP+15). |
LINK A6,#-16 ;create a stack frame of 16 bytes. Now you can safely write to (SP+0) thru (SP+15). |
||
Line 95: | Line 95: | ||
UNLK A6 ;free the stack frame |
UNLK A6 ;free the stack frame |
||
RTS</ |
RTS</syntaxhighlight> |
||
<code>LINK An, #-disp</code> is effectively equivalent to the following: |
<code>LINK An, #-disp</code> is effectively equivalent to the following: |
||
< |
<syntaxhighlight lang="68000devpac">MOVE.L An,-(SP) |
||
MOVEA.L SP,An |
MOVEA.L SP,An |
||
LEA (-disp,SP),SP</ |
LEA (-disp,SP),SP</syntaxhighlight> |
||
You can use negative offsets of <code>An</code> or positive offsets of <code>SP</code> to refer to the same memory region. |
You can use negative offsets of <code>An</code> or positive offsets of <code>SP</code> to refer to the same memory region. |
||
Line 108: | Line 108: | ||
Action! does not have a stack for storing variables. When variable is declared in a procedure or function it is declared globally once at the beginning of the program even if the subroutine is not used. In the Action! Tool Kit there is a module for dynamic allocation and deallocation of memory. The user must type in the monitor the following command after compilation and before running the program!<pre>SET EndProg=*</pre> |
Action! does not have a stack for storing variables. When variable is declared in a procedure or function it is declared globally once at the beginning of the program even if the subroutine is not used. In the Action! Tool Kit there is a module for dynamic allocation and deallocation of memory. The user must type in the monitor the following command after compilation and before running the program!<pre>SET EndProg=*</pre> |
||
{{libheader|Action! Tool Kit}} |
{{libheader|Action! Tool Kit}} |
||
< |
<syntaxhighlight lang="action!">CARD EndProg ;required for ALLOCATE.ACT |
||
INCLUDE "D2:ALLOCATE.ACT" ;from the Action! Tool Kit. You must type 'SET EndProg=*' from the monitor after compiling, but before running this program! |
INCLUDE "D2:ALLOCATE.ACT" ;from the Action! Tool Kit. You must type 'SET EndProg=*' from the monitor after compiling, but before running this program! |
||
Line 121: | Line 121: | ||
SetBlock(ptr,SIZE,$FF) ;fill the memory block with $FF |
SetBlock(ptr,SIZE,$FF) ;fill the memory block with $FF |
||
Free(ptr,SIZE) ;free allocated memory |
Free(ptr,SIZE) ;free allocated memory |
||
RETURN</ |
RETURN</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Memory_allocation.png Screenshot from Atari 8-bit computer] |
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Memory_allocation.png Screenshot from Atari 8-bit computer] |
||
Line 128: | Line 128: | ||
===Stack=== |
===Stack=== |
||
[[Stack]] in [[Ada]] is allocated by declaration of an object in some scope of a block or else a subprogram: |
[[Stack]] in [[Ada]] is allocated by declaration of an object in some scope of a block or else a subprogram: |
||
< |
<syntaxhighlight lang="ada">declare |
||
X : Integer; -- Allocated on the stack |
X : Integer; -- Allocated on the stack |
||
begin |
begin |
||
... |
... |
||
end; -- X is freed</ |
end; -- X is freed</syntaxhighlight> |
||
===Heap=== |
===Heap=== |
||
[[Heap]] is allocated with the allocator '''new''' on the context where a pool-unspecific pointer is expected: |
[[Heap]] is allocated with the allocator '''new''' on the context where a pool-unspecific pointer is expected: |
||
< |
<syntaxhighlight lang="ada">declare |
||
type Integer_Ptr is access Integer; |
type Integer_Ptr is access Integer; |
||
Ptr : Integer_Ptr := new Integer; -- Allocated in the heap |
Ptr : Integer_Ptr := new Integer; -- Allocated in the heap |
||
begin |
begin |
||
... |
... |
||
end; -- Memory is freed because Integer_Ptr is finalized</ |
end; -- Memory is freed because Integer_Ptr is finalized</syntaxhighlight> |
||
The memory allocated by '''new''' is freed when: |
The memory allocated by '''new''' is freed when: |
||
* the type of the pointer leaves the scope; |
* the type of the pointer leaves the scope; |
||
* the memory pool is finalized |
* the memory pool is finalized |
||
* an instance of Ada.Unchecked_Deallocation is explicitly called on the pointer |
* an instance of Ada.Unchecked_Deallocation is explicitly called on the pointer |
||
< |
<syntaxhighlight lang="ada">declare |
||
type Integer_Ptr is access Integer; |
type Integer_Ptr is access Integer; |
||
procedure Free is new Ada.Unchecked_Deallocation (Integer, Integer_Ptr) |
procedure Free is new Ada.Unchecked_Deallocation (Integer, Integer_Ptr) |
||
Line 152: | Line 152: | ||
Free (Ptr); -- Explicit deallocation |
Free (Ptr); -- Explicit deallocation |
||
... |
... |
||
end;</ |
end;</syntaxhighlight> |
||
===User pool=== |
===User pool=== |
||
The allocator '''new''' also allocates memory in the user-defined storage pool when the pointer bound to the pool. |
The allocator '''new''' also allocates memory in the user-defined storage pool when the pointer bound to the pool. |
||
Line 160: | Line 160: | ||
===Implicit allocation=== |
===Implicit allocation=== |
||
Elaboration of compilation units may result in allocation of the objects declared in these units. For example: |
Elaboration of compilation units may result in allocation of the objects declared in these units. For example: |
||
< |
<syntaxhighlight lang="ada">package P is |
||
X : Integer; -- Allocated in the result the package elaboration |
X : Integer; -- Allocated in the result the package elaboration |
||
end P;</ |
end P;</syntaxhighlight> |
||
The memory required by the object may be allocated statically or dynamically depending on the time of elaboration and its context. Objects declared in the library level packages are equivalent to what in some languages is called ''static'' object. |
The memory required by the object may be allocated statically or dynamically depending on the time of elaboration and its context. Objects declared in the library level packages are equivalent to what in some languages is called ''static'' object. |
||
Line 170: | Line 170: | ||
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}} |
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}} |
||
Given: |
Given: |
||
< |
<syntaxhighlight lang="algol68">MODE MYSTRUCT = STRUCT(INT i, j, k, REAL r, COMPL c);</syntaxhighlight> |
||
===Stack=== |
===Stack=== |
||
< |
<syntaxhighlight lang="algol68">REF MYSTRUCT l = LOC MYSTRUCT;</syntaxhighlight> |
||
===Heap=== |
===Heap=== |
||
< |
<syntaxhighlight lang="algol68">REF MYSTRUCT h = HEAP MYSTRUCT;</syntaxhighlight> |
||
===User pool=== |
===User pool=== |
||
< |
<syntaxhighlight lang="algol68">[666]MYSTRUCT pool; |
||
INT new pool := LWB pool-1; |
INT new pool := LWB pool-1; |
||
REF MYSTRUCT p = pool[new pool +:=1];</ |
REF MYSTRUCT p = pool[new pool +:=1];</syntaxhighlight> |
||
===External memory=== |
===External memory=== |
||
Without extensions it is not possible to access external memory. However most implementations have such an extension! |
Without extensions it is not possible to access external memory. However most implementations have such an extension! |
||
===Implicit allocation=== |
===Implicit allocation=== |
||
<lang |
<syntaxhighlight lang="algol68">MYSTRUCT i;</syntaxhighlight> |
||
=={{header|ALGOL W}}== |
=={{header|ALGOL W}}== |
||
Algol W has garbage collected dynamic allocation for record structures. |
Algol W has garbage collected dynamic allocation for record structures. |
||
< |
<syntaxhighlight lang="algolw">begin |
||
% define a record structure - instances must be created dynamically % |
% define a record structure - instances must be created dynamically % |
||
record Element ( integer atomicNumber; string(16) name ); |
record Element ( integer atomicNumber; string(16) name ); |
||
Line 195: | Line 195: | ||
X := Element( 2, "Helium" ) |
X := Element( 2, "Helium" ) |
||
% the memory allocated will now be garbage collected - there is no explicit de-allocation % |
% the memory allocated will now be garbage collected - there is no explicit de-allocation % |
||
end.</ |
end.</syntaxhighlight> |
||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
< |
<syntaxhighlight lang="autohotkey">VarSetCapacity(Var, 10240000) ; allocate 10 megabytes |
||
VarSetCapacity(Var, 0) ; free it</ |
VarSetCapacity(Var, 0) ; free it</syntaxhighlight> |
||
=={{header|Axe}}== |
=={{header|Axe}}== |
||
Axe does not provide runtime support for a heap, so memory must be allocated statically. |
Axe does not provide runtime support for a heap, so memory must be allocated statically. |
||
< |
<syntaxhighlight lang="axe">Buff(100)→Str1 |
||
.Str1 points to a 100-byte memory region allocated at compile time</ |
.Str1 points to a 100-byte memory region allocated at compile time</syntaxhighlight> |
||
The optional second parameter to Buff() allows you to specify the byte to be filled with (default is zero). |
The optional second parameter to Buff() allows you to specify the byte to be filled with (default is zero). |
||
Line 210: | Line 210: | ||
=={{header|BBC BASIC}}== |
=={{header|BBC BASIC}}== |
||
===Heap=== |
===Heap=== |
||
< |
<syntaxhighlight lang="bbcbasic"> size% = 12345 |
||
DIM mem% size%-1 |
DIM mem% size%-1 |
||
PRINT ; size% " bytes of heap allocated at " ; mem%</ |
PRINT ; size% " bytes of heap allocated at " ; mem%</syntaxhighlight> |
||
Memory allocated from the heap is only freed on program termination or CLEAR. |
Memory allocated from the heap is only freed on program termination or CLEAR. |
||
===Stack=== |
===Stack=== |
||
< |
<syntaxhighlight lang="bbcbasic"> size% = 12345 |
||
PROCstack(size%) |
PROCstack(size%) |
||
END |
END |
||
Line 223: | Line 223: | ||
DIM mem% LOCAL s%-1 |
DIM mem% LOCAL s%-1 |
||
PRINT ; s% " bytes of stack allocated at " ; mem% |
PRINT ; s% " bytes of stack allocated at " ; mem% |
||
ENDPROC</ |
ENDPROC</syntaxhighlight> |
||
Memory allocated from the stack is freed on exit from the FN or PROC. |
Memory allocated from the stack is freed on exit from the FN or PROC. |
||
Line 232: | Line 232: | ||
The Bracmat functions <code>alc$</code> and <code>fre$</code> call the C-functions <code>malloc()</code> and <code>free()</code>, respectively. Writing and reading to and from allocated memory is done with the poke and peek functions <code>pok$</code> and <code>pee$</code>. These funtions write and read in chunks of 1 (default), 2 or 4 bytes. No need to say that all these low-level functions easily can create havoc and should be disabled in serious applications that don't need them. (There are compiler preprocessor macros to do that.) |
The Bracmat functions <code>alc$</code> and <code>fre$</code> call the C-functions <code>malloc()</code> and <code>free()</code>, respectively. Writing and reading to and from allocated memory is done with the poke and peek functions <code>pok$</code> and <code>pee$</code>. These funtions write and read in chunks of 1 (default), 2 or 4 bytes. No need to say that all these low-level functions easily can create havoc and should be disabled in serious applications that don't need them. (There are compiler preprocessor macros to do that.) |
||
< |
<syntaxhighlight lang="bracmat">( alc$2000:?p {allocate 2000 bytes} |
||
& pok$(!p,123456789,4) { poke a large value as a 4 byte integer } |
& pok$(!p,123456789,4) { poke a large value as a 4 byte integer } |
||
& pok$(!p+4,0,4) { poke zeros in the next 4 bytes } |
& pok$(!p+4,0,4) { poke zeros in the next 4 bytes } |
||
Line 241: | Line 241: | ||
& out$(pee$(!p+1000,2)) { peek some uninitialized data } |
& out$(pee$(!p+1000,2)) { peek some uninitialized data } |
||
& fre$!p { free the memory } |
& fre$!p { free the memory } |
||
&);</ |
&);</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>21 |
<pre>21 |
||
Line 252: | Line 252: | ||
The functions <tt>malloc</tt>, <tt>calloc</tt> and <tt>realloc</tt> take memory from the heap. This memory ''should'' be released with <tt>free</tt> and it's suitable for sharing memory among threads. |
The functions <tt>malloc</tt>, <tt>calloc</tt> and <tt>realloc</tt> take memory from the heap. This memory ''should'' be released with <tt>free</tt> and it's suitable for sharing memory among threads. |
||
< |
<syntaxhighlight lang="c">#include <stdlib.h> |
||
/* size of "members", in bytes */ |
/* size of "members", in bytes */ |
||
Line 269: | Line 269: | ||
free(ints); free(int2); |
free(ints); free(int2); |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
Variables declared inside a block (a function or inside a function) take room from the stack and survive until the "block" is in execution (and their scope is local). |
Variables declared inside a block (a function or inside a function) take room from the stack and survive until the "block" is in execution (and their scope is local). |
||
< |
<syntaxhighlight lang="c">int func() |
||
{ |
{ |
||
int ints[NMEMB]; /* it resembles malloc ... */ |
int ints[NMEMB]; /* it resembles malloc ... */ |
||
Line 289: | Line 289: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{works with|gcc}} |
{{works with|gcc}} |
||
Line 295: | Line 295: | ||
The libc provided by [[gcc]] (and present on other "systems" too) has the <tt>alloca</tt> function which allows to ask for memory on the stack explicitly; the memory is deallocated when the function that asked for the memory ends (it is, in practice, the same behaviour for automatic variables). The usage is the same as for functions like <tt>malloc</tt> |
The libc provided by [[gcc]] (and present on other "systems" too) has the <tt>alloca</tt> function which allows to ask for memory on the stack explicitly; the memory is deallocated when the function that asked for the memory ends (it is, in practice, the same behaviour for automatic variables). The usage is the same as for functions like <tt>malloc</tt> |
||
< |
<syntaxhighlight lang="c">#include <alloca.h> |
||
int *funcA() |
int *funcA() |
||
{ |
{ |
||
Line 302: | Line 302: | ||
return ints; /* BUT THIS IS WRONG! It is not like malloc: the memory |
return ints; /* BUT THIS IS WRONG! It is not like malloc: the memory |
||
does not "survive"! */ |
does not "survive"! */ |
||
}</ |
}</syntaxhighlight> |
||
Variables declared outside any block and function or inside a function but prepended with the attribute <tt>static</tt> live as long as the program lives and the memory for them is statically given (e.g. through a .bss block). |
Variables declared outside any block and function or inside a function but prepended with the attribute <tt>static</tt> live as long as the program lives and the memory for them is statically given (e.g. through a .bss block). |
||
< |
<syntaxhighlight lang="c">/* this is global */ |
||
int integers[NMEMB]; /* should be initialized with 0s */ |
int integers[NMEMB]; /* should be initialized with 0s */ |
||
Line 319: | Line 319: | ||
{ |
{ |
||
integers[0] = a; |
integers[0] = a; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
C# is a managed language, so memory allocation is usually not done manually. However, in unsafe code it is possible to declare and operate on pointers. |
C# is a managed language, so memory allocation is usually not done manually. However, in unsafe code it is possible to declare and operate on pointers. |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Runtime.InteropServices; |
using System.Runtime.InteropServices; |
||
Line 359: | Line 359: | ||
static extern int HeapSize(int hHeap, int flags, void* block); |
static extern int HeapSize(int hHeap, int flags, void* block); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
While the C allocation functions are also available in C++, their use is discouraged. Instead, C++ provides <code>new</code> and <code>delete</code> for memory allocation and deallocation. Those function don't just allocate memory, but also initialize objects. Also, deallocation is coupled with destruction. |
While the C allocation functions are also available in C++, their use is discouraged. Instead, C++ provides <code>new</code> and <code>delete</code> for memory allocation and deallocation. Those function don't just allocate memory, but also initialize objects. Also, deallocation is coupled with destruction. |
||
< |
<syntaxhighlight lang="cpp">#include <string> |
||
int main() |
int main() |
||
Line 385: | Line 385: | ||
p2 = new std::string[10]; // allocate an array of 10 strings, default-initialized |
p2 = new std::string[10]; // allocate an array of 10 strings, default-initialized |
||
delete[] p2; // deallocate it |
delete[] p2; // deallocate it |
||
}</ |
}</syntaxhighlight> |
||
Note that memory allocated with C allocation functions (<code>malloc</code>, <code>calloc</code>, <code>realloc</code>) must always be deallocated with <code>free</code>, memory allocated with non-array <code>new</code> must always be deallocated with <code>delete</code>, and memory allocated with array <code>new</code> must always deallocated with <code>delete[]</code>. Memory allocated with new also cannot be resized with <code>realloc</code>. |
Note that memory allocated with C allocation functions (<code>malloc</code>, <code>calloc</code>, <code>realloc</code>) must always be deallocated with <code>free</code>, memory allocated with non-array <code>new</code> must always be deallocated with <code>delete</code>, and memory allocated with array <code>new</code> must always deallocated with <code>delete[]</code>. Memory allocated with new also cannot be resized with <code>realloc</code>. |
||
Line 391: | Line 391: | ||
Besides the new expressions shown above, pure memory allocation/deallocation without object initialization/destruction can also be done through <code>operator new</code>: |
Besides the new expressions shown above, pure memory allocation/deallocation without object initialization/destruction can also be done through <code>operator new</code>: |
||
< |
<syntaxhighlight lang="cpp">int main() |
||
{ |
{ |
||
void* memory = operator new(20); // allocate 20 bytes of memory |
void* memory = operator new(20); // allocate 20 bytes of memory |
||
operator delete(memory); // deallocate it |
operator delete(memory); // deallocate it |
||
}</ |
}</syntaxhighlight> |
||
There's also a placement form of new, which allows to construct objects at an arbitrary adress (provided it is correctly aligned, and there's enough memory): |
There's also a placement form of new, which allows to construct objects at an arbitrary adress (provided it is correctly aligned, and there's enough memory): |
||
< |
<syntaxhighlight lang="cpp">#include <new> |
||
int main() |
int main() |
||
Line 409: | Line 409: | ||
int* p = new(&data) int(3); // construct an int at the beginning of data |
int* p = new(&data) int(3); // construct an int at the beginning of data |
||
new(p+1) int(5); // construct another int directly following |
new(p+1) int(5); // construct another int directly following |
||
}</ |
}</syntaxhighlight> |
||
Indeed, code like <code>int* p = new int(3);</code> is roughly (but not exactly) equivalent to the following sequence: |
Indeed, code like <code>int* p = new int(3);</code> is roughly (but not exactly) equivalent to the following sequence: |
||
< |
<syntaxhighlight lang="cpp">void* memory_for_p = operator new(sizeof(int)); |
||
int* p = new(memory_for_p) int(3);</ |
int* p = new(memory_for_p) int(3);</syntaxhighlight> |
||
Normally, new throws an exception if the allocation fails. there's a non-throwing variant which returns a null pointer instead: |
Normally, new throws an exception if the allocation fails. there's a non-throwing variant which returns a null pointer instead: |
||
< |
<syntaxhighlight lang="cpp">#include <new> |
||
int* p = new(std::nothrow) int(3);</ |
int* p = new(std::nothrow) int(3);</syntaxhighlight> |
||
Note that the nothrow variant does <em>not</em> prevent any exceptions to be thrown from the constructor of an object created with new. It only prevents exceptions due to memory allocation failure. |
Note that the nothrow variant does <em>not</em> prevent any exceptions to be thrown from the constructor of an object created with new. It only prevents exceptions due to memory allocation failure. |
||
It is also possible to implement user-defined variations of operator new. One possibility is to define class-based operator new/operator delete: |
It is also possible to implement user-defined variations of operator new. One possibility is to define class-based operator new/operator delete: |
||
< |
<syntaxhighlight lang="cpp">#include <cstddef> |
||
#include <cstdlib> |
#include <cstdlib> |
||
#include <new> |
#include <new> |
||
Line 447: | Line 447: | ||
int* p2 = new int; // uses default operator new |
int* p2 = new int; // uses default operator new |
||
delete p2; // uses default operator delete |
delete p2; // uses default operator delete |
||
}</ |
}</syntaxhighlight> |
||
Another possibility is to define new arguments for placement new syntax, e.g. |
Another possibility is to define new arguments for placement new syntax, e.g. |
||
< |
<syntaxhighlight lang="cpp">class arena { /* ... */ }; |
||
void* operator new(std::size_t size, arena& a) |
void* operator new(std::size_t size, arena& a) |
||
Line 464: | Line 464: | ||
arena whatever(/* ... */); |
arena whatever(/* ... */); |
||
int* p = new(whatever) int(3); // uses operator new from above to allocate from the arena whatever</ |
int* p = new(whatever) int(3); // uses operator new from above to allocate from the arena whatever</syntaxhighlight> |
||
Note that there is ''no'' placement delete syntax; the placement operator delete is invoked by the compiler only in case the constructor of the newed object throws. Therefore for placement newed object deletion the two steps must be done explicitly: |
Note that there is ''no'' placement delete syntax; the placement operator delete is invoked by the compiler only in case the constructor of the newed object throws. Therefore for placement newed object deletion the two steps must be done explicitly: |
||
< |
<syntaxhighlight lang="cpp">class MyClass { /*...*/ }; |
||
int main() |
int main() |
||
Line 474: | Line 474: | ||
p->~MyClass(); // explicitly destruct *p |
p->~MyClass(); // explicitly destruct *p |
||
operator delete(p, whatever); // explicitly deallocate the memory |
operator delete(p, whatever); // explicitly deallocate the memory |
||
}</ |
}</syntaxhighlight> |
||
=={{header|COBOL}}== |
=={{header|COBOL}}== |
||
Line 480: | Line 480: | ||
Manual memory allocation is primarily done using <code>ALLOCATE</code> and <code>FREE</code>. They are used with data items with a <code>BASED</code> clause, which indicates that the data will be allocated at runtime. A <code>BASED</code> data item cannot be used before it has been allocated or after it has been freed. Example usage: |
Manual memory allocation is primarily done using <code>ALLOCATE</code> and <code>FREE</code>. They are used with data items with a <code>BASED</code> clause, which indicates that the data will be allocated at runtime. A <code>BASED</code> data item cannot be used before it has been allocated or after it has been freed. Example usage: |
||
< |
<syntaxhighlight lang="cobol"> PROGRAM-ID. memory-allocation. |
||
DATA DIVISION. |
DATA DIVISION. |
||
Line 494: | Line 494: | ||
GOBACK |
GOBACK |
||
.</ |
.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 506: | Line 506: | ||
This behavior can be observed with the (not good for actual use) code: |
This behavior can be observed with the (not good for actual use) code: |
||
< |
<syntaxhighlight lang="lisp">(defun show-allocation () |
||
(let ((a (cons 1 2)) |
(let ((a (cons 1 2)) |
||
(b (cons 1 2))) |
(b (cons 1 2))) |
||
(declare (dynamic-extent b)) |
(declare (dynamic-extent b)) |
||
(list a b)))</ |
(list a b)))</syntaxhighlight> |
||
<lang |
<syntaxhighlight lang="lisp">(show-allocation)</syntaxhighlight> |
||
produces |
produces |
||
<pre> |
<pre> |
||
Line 519: | Line 519: | ||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang="d">// D is a system language so its memory management is refined. |
||
// D supports thread-local memory on default, global memory, memory |
// D supports thread-local memory on default, global memory, memory |
||
// allocated on the stack, the C heap, or the D heap managed by a |
// allocated on the stack, the C heap, or the D heap managed by a |
||
Line 653: | Line 653: | ||
GC.free(ptr4); // This is optional. |
GC.free(ptr4); // This is optional. |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Test destructor |
<pre>Test destructor |
||
Line 666: | Line 666: | ||
E is a memory-safe language and does not generally work with explicit deallocation. As in Python and Java, you can create arrays of specific data types which will, by any decent implementation, be compactly represented. |
E is a memory-safe language and does not generally work with explicit deallocation. As in Python and Java, you can create arrays of specific data types which will, by any decent implementation, be compactly represented. |
||
< |
<syntaxhighlight lang="e">? <elib:tables.makeFlexList>.fromType(<type:java.lang.Byte>, 128) |
||
# value: [].diverge()</ |
# value: [].diverge()</syntaxhighlight> |
||
The above creates an array with an initial capacity of 128 bytes (1 kilobit) of storage (though it does not have any elements). (The Java type name is left-over from E's Java-scripting history and will eventually be deprecated in favor of a more appropriate name.) The array will be deallocated when there are no references to it. |
The above creates an array with an initial capacity of 128 bytes (1 kilobit) of storage (though it does not have any elements). (The Java type name is left-over from E's Java-scripting history and will eventually be deprecated in favor of a more appropriate name.) The array will be deallocated when there are no references to it. |
||
Line 684: | Line 684: | ||
To just allocate some bytes, <code>malloc</code> is used. This memory has to be <code>free</code>d again of course. |
To just allocate some bytes, <code>malloc</code> is used. This memory has to be <code>free</code>d again of course. |
||
< |
<syntaxhighlight lang="factor">2000 malloc (...do stuff..) free</syntaxhighlight> |
||
To increase safety and reduce memory leaks, there are specialized words available to help you manage your memory. If you use <code>&free</code> together with <code>with-destructors</code> your memory gets freed even in the presence of exceptions. |
To increase safety and reduce memory leaks, there are specialized words available to help you manage your memory. If you use <code>&free</code> together with <code>with-destructors</code> your memory gets freed even in the presence of exceptions. |
||
< |
<syntaxhighlight lang="factor">STRUCT: foo { a int } { b foo* } ; |
||
[ |
[ |
||
foo malloc-struct &free ! gets freed at end of the current with-destructors scope |
foo malloc-struct &free ! gets freed at end of the current with-destructors scope |
||
! do stuff |
! do stuff |
||
] with-destructors</ |
] with-destructors</syntaxhighlight> |
||
Memory allocated with any of these malloc variants resides in the (non-garbage-collected) heap. |
Memory allocated with any of these malloc variants resides in the (non-garbage-collected) heap. |
||
Line 700: | Line 700: | ||
===Dictionary=== |
===Dictionary=== |
||
All Forth implementations have a stack-like memory space called the ''dictionary''. It is used both for code definitions and data structures. |
All Forth implementations have a stack-like memory space called the ''dictionary''. It is used both for code definitions and data structures. |
||
< |
<syntaxhighlight lang="forth">unused . \ memory available for use in dictionary |
||
here . \ current dictionary memory pointer |
here . \ current dictionary memory pointer |
||
: mem, ( addr len -- ) here over allot swap move ; |
: mem, ( addr len -- ) here over allot swap move ; |
||
Line 709: | Line 709: | ||
create struct 0 , 10 , char A c, ," string" |
create struct 0 , 10 , char A c, ," string" |
||
unused . |
unused . |
||
here .</ |
here .</syntaxhighlight> |
||
Dictionary space is meant for static code definitions and supporting data structures, so it is not as easy to deallocate from it. For ad-hoc allocations without intervening definitions, you may give a negative value to ALLOT to reclaim the space. You may also lay down a named MARKER to reclaim the space used by all subsequent definitions. |
Dictionary space is meant for static code definitions and supporting data structures, so it is not as easy to deallocate from it. For ad-hoc allocations without intervening definitions, you may give a negative value to ALLOT to reclaim the space. You may also lay down a named MARKER to reclaim the space used by all subsequent definitions. |
||
< |
<syntaxhighlight lang="forth">marker foo |
||
: temp ... ; |
: temp ... ; |
||
create dummy 300 allot |
create dummy 300 allot |
||
-150 allot \ trim the size of dummy by 150 bytes |
-150 allot \ trim the size of dummy by 150 bytes |
||
foo \ removes foo, temp, and dummy from the list of definitions</ |
foo \ removes foo, temp, and dummy from the list of definitions</syntaxhighlight> |
||
===Heap=== |
===Heap=== |
||
Most Forth implementations also give access to a larger random-access memory heap. |
Most Forth implementations also give access to a larger random-access memory heap. |
||
< |
<syntaxhighlight lang="forth">4096 allocate throw ( addr ) |
||
dup 4096 erase |
dup 4096 erase |
||
( addr ) free throw</ |
( addr ) free throw</syntaxhighlight> |
||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
< |
<syntaxhighlight lang="fortran">program allocation_test |
||
implicit none |
implicit none |
||
real, dimension(:), allocatable :: vector |
real, dimension(:), allocatable :: vector |
||
Line 739: | Line 739: | ||
deallocate(matrix) ! Deallocate a matrix |
deallocate(matrix) ! Deallocate a matrix |
||
deallocate(ptr) ! Deallocate a pointer |
deallocate(ptr) ! Deallocate a pointer |
||
end program allocation_test</ |
end program allocation_test</syntaxhighlight> |
||
Line 745: | Line 745: | ||
{{trans|BBC BASIC}} |
{{trans|BBC BASIC}} |
||
===Heap=== |
===Heap=== |
||
< |
<syntaxhighlight lang="freebasic">Dim As Integer size = 12345 |
||
Dim As Integer mem = size-1 |
Dim As Integer mem = size-1 |
||
Print size; " bytes of heap allocated at " ; mem |
Print size; " bytes of heap allocated at " ; mem |
||
Clear (mem, , 10) |
Clear (mem, , 10) |
||
Print size; " bytes of heap allocated at " ; mem</ |
Print size; " bytes of heap allocated at " ; mem</syntaxhighlight> |
||
Memory allocated from the heap is only freed on program termination or CLEAR |
Memory allocated from the heap is only freed on program termination or CLEAR |
||
===Stack=== |
===Stack=== |
||
< |
<syntaxhighlight lang="freebasic">Dim As Integer size = 12345 |
||
Dim As Integer mem = size-1 |
Dim As Integer mem = size-1 |
||
Line 762: | Line 762: | ||
Stack(size) |
Stack(size) |
||
Print size; " bytes of stack allocated at " ; mem</ |
Print size; " bytes of stack allocated at " ; mem</syntaxhighlight> |
||
Memory allocated from the stack is freed on exit from the Sub/Function |
Memory allocated from the stack is freed on exit from the Sub/Function |
||
Line 768: | Line 768: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
All memory in Go is transparently managed by the runtime and the language specification does not even contain the words stack or heap. Behind the scenes it has a single shared heap and a stack for each goroutine. Stacks for goroutines are initially 4K, but grow dyanamically as needed. Function parameters and variables declared within a function typically live on the stack, but the runtime will freely move them to the heap as needed. For example, in |
All memory in Go is transparently managed by the runtime and the language specification does not even contain the words stack or heap. Behind the scenes it has a single shared heap and a stack for each goroutine. Stacks for goroutines are initially 4K, but grow dyanamically as needed. Function parameters and variables declared within a function typically live on the stack, but the runtime will freely move them to the heap as needed. For example, in |
||
< |
<syntaxhighlight lang="go">func inc(n int) { |
||
x := n + 1 |
x := n + 1 |
||
println(x) |
println(x) |
||
}</ |
}</syntaxhighlight> |
||
Parameter n and variable x will exist on the stack. |
Parameter n and variable x will exist on the stack. |
||
< |
<syntaxhighlight lang="go">func inc(n int) *int { |
||
x := n + 1 |
x := n + 1 |
||
return &x |
return &x |
||
}</ |
}</syntaxhighlight> |
||
In the above, however, storage for x will be allocated on the heap because this storage is still referenced after inc returns. |
In the above, however, storage for x will be allocated on the heap because this storage is still referenced after inc returns. |
||
In general, taking the address of an object allocates it on the heap. A conseqence is that given |
In general, taking the address of an object allocates it on the heap. A conseqence is that given |
||
< |
<syntaxhighlight lang="go">type s struct{a, b int}</syntaxhighlight> |
||
the following two expressions are equivalent. |
the following two expressions are equivalent. |
||
<lang |
<syntaxhighlight lang="go">&s{}</syntaxhighlight> |
||
<lang |
<syntaxhighlight lang="go">new(s)</syntaxhighlight> |
||
Yes, new allocates on the heap. |
Yes, new allocates on the heap. |
||
Line 789: | Line 789: | ||
Examples, |
Examples, |
||
< |
<syntaxhighlight lang="go">make([]int, 3) |
||
make(map[int]int) |
make(map[int]int) |
||
make(chan int)</ |
make(chan int)</syntaxhighlight> |
||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
Line 797: | Line 797: | ||
You usually only need to do low-level memory management in Haskell when interfacing with code written in other languages (particularly C). At its most basic level, Haskell provides malloc()/free()-like operations in the IO monad. |
You usually only need to do low-level memory management in Haskell when interfacing with code written in other languages (particularly C). At its most basic level, Haskell provides malloc()/free()-like operations in the IO monad. |
||
< |
<syntaxhighlight lang="haskell">import Foreign |
||
bytealloc :: IO () |
bytealloc :: IO () |
||
Line 805: | Line 805: | ||
allocaBytes 100 $ \a -> -- Allocate 100 bytes; automatically |
allocaBytes 100 $ \a -> -- Allocate 100 bytes; automatically |
||
-- freed when closure finishes |
-- freed when closure finishes |
||
poke (a::Ptr Word32) 0</ |
poke (a::Ptr Word32) 0</syntaxhighlight> |
||
Slightly more sophisticated functions are available for automatically determining the amount of memory necessary to store a value of a specific type. The type is determined by type inference (in this example I use explicit manual type annotations, because poke is polymorphic). |
Slightly more sophisticated functions are available for automatically determining the amount of memory necessary to store a value of a specific type. The type is determined by type inference (in this example I use explicit manual type annotations, because poke is polymorphic). |
||
< |
<syntaxhighlight lang="haskell">import Foreign |
||
typedalloc :: IO () |
typedalloc :: IO () |
||
Line 816: | Line 816: | ||
poke w (100 :: Word32) |
poke w (100 :: Word32) |
||
free w |
free w |
||
alloca $ \a -> poke a (100 :: Word32)</ |
alloca $ \a -> poke a (100 :: Word32)</syntaxhighlight> |
||
By the typing rules of Haskell, w must have the type 'Ptr Word32' (pointer to 32-bit word), which is how malloc knows how much memory to allocate. |
By the typing rules of Haskell, w must have the type 'Ptr Word32' (pointer to 32-bit word), which is how malloc knows how much memory to allocate. |
||
Line 824: | Line 824: | ||
Icon and Unicon provide fully automatic memory allocation. Memory is allocated when each |
Icon and Unicon provide fully automatic memory allocation. Memory is allocated when each |
||
structure is created and reclaimed after it is no longer referenced. For example: |
structure is created and reclaimed after it is no longer referenced. For example: |
||
< |
<syntaxhighlight lang="unicon"> |
||
t := table() # The table's memory is allocated |
t := table() # The table's memory is allocated |
||
#... do things with t |
#... do things with t |
||
t := &null # The table's memory can be reclaimed |
t := &null # The table's memory can be reclaimed |
||
</syntaxhighlight> |
|||
</lang> |
|||
For structures whose only reference is held in a local variable, that reference is removed |
For structures whose only reference is held in a local variable, that reference is removed |
||
when the local context is exited (i.e. when procedures return) and the storage is then |
when the local context is exited (i.e. when procedures return) and the storage is then |
||
Line 839: | Line 839: | ||
Example of explicit [http://www.jsoftware.com/help/user/memory_management.htm memory allocation]: |
Example of explicit [http://www.jsoftware.com/help/user/memory_management.htm memory allocation]: |
||
< |
<syntaxhighlight lang="j"> require 'dll' |
||
mema 1000 |
mema 1000 |
||
57139856</ |
57139856</syntaxhighlight> |
||
Here, 57139856 is the result of mema -- it refers to 1000 bytes of memory. |
Here, 57139856 is the result of mema -- it refers to 1000 bytes of memory. |
||
Line 847: | Line 847: | ||
To free it: |
To free it: |
||
<lang |
<syntaxhighlight lang="j">memf 57139856</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
You don't get much control over memory in Java, but here's what you can do: |
You don't get much control over memory in Java, but here's what you can do: |
||
< |
<syntaxhighlight lang="java">//All of these objects will be deallocated automatically once the program leaves |
||
//their scope and there are no more pointers to the objects |
//their scope and there are no more pointers to the objects |
||
Object foo = new Object(); //Allocate an Object and a reference to it |
Object foo = new Object(); //Allocate an Object and a reference to it |
||
int[] fooArray = new int[size]; //Allocate all spaces in an array and a reference to it |
int[] fooArray = new int[size]; //Allocate all spaces in an array and a reference to it |
||
int x = 0; //Allocate an integer and set its value to 0</ |
int x = 0; //Allocate an integer and set its value to 0</syntaxhighlight> |
||
There is no real destructor in Java as there is in C++, but there is the <tt>finalize</tt> method. From the [http://java.sun.com/javase/6/docs/api/java/lang/Object.html#finalize() Java 6 JavaDocs]: |
There is no real destructor in Java as there is in C++, but there is the <tt>finalize</tt> method. From the [http://java.sun.com/javase/6/docs/api/java/lang/Object.html#finalize() Java 6 JavaDocs]: |
||
''The general contract of finalize is that it is invoked if and when the JavaTM virtual machine has determined that there is no longer any means by which this object can be accessed by any thread that has not yet died, except as a result of an action taken by the finalization of some other object or class which is ready to be finalized. The finalize method may take any action, including making this object available again to other threads; the usual purpose of finalize, however, is to perform cleanup actions before the object is irrevocably discarded. For example, the finalize method for an object that represents an input/output connection might perform explicit I/O transactions to break the connection before the object is permanently discarded.'' |
''The general contract of finalize is that it is invoked if and when the JavaTM virtual machine has determined that there is no longer any means by which this object can be accessed by any thread that has not yet died, except as a result of an action taken by the finalization of some other object or class which is ready to be finalized. The finalize method may take any action, including making this object available again to other threads; the usual purpose of finalize, however, is to perform cleanup actions before the object is irrevocably discarded. For example, the finalize method for an object that represents an input/output connection might perform explicit I/O transactions to break the connection before the object is permanently discarded.'' |
||
< |
<syntaxhighlight lang="java">public class Blah{ |
||
//...other methods/data members... |
//...other methods/data members... |
||
protected void finalize() throws Throwable{ |
protected void finalize() throws Throwable{ |
||
Line 865: | Line 865: | ||
} |
} |
||
//...other methods/data members... |
//...other methods/data members... |
||
}</ |
}</syntaxhighlight> |
||
Note, though, that there is '''''no guarantee''''' that the <tt>finalize</tt> method will ever be called, as this trivial program demonstrates: |
Note, though, that there is '''''no guarantee''''' that the <tt>finalize</tt> method will ever be called, as this trivial program demonstrates: |
||
< |
<syntaxhighlight lang="java">public class NoFinalize { |
||
public static final void main(String[] params) { |
public static final void main(String[] params) { |
||
NoFinalize nf = new NoFinalize(); |
NoFinalize nf = new NoFinalize(); |
||
Line 879: | Line 879: | ||
System.out.println("finalized"); |
System.out.println("finalized"); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
When run using Sun's JVM implementation, the above simply outputs "created". Therefore, you cannot rely on <tt>finalize</tt> for cleanup. |
When run using Sun's JVM implementation, the above simply outputs "created". Therefore, you cannot rely on <tt>finalize</tt> for cleanup. |
||
Line 885: | Line 885: | ||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
Julia has memory management. Objects are freed from memory automatically. Because arrays such as vectors and matrices, unlike lists, can have fixed size allocations in memory, these can be allocated implicitly with a call to a function returning a vector, or explicitly by assigning the memory to a variable: |
Julia has memory management. Objects are freed from memory automatically. Because arrays such as vectors and matrices, unlike lists, can have fixed size allocations in memory, these can be allocated implicitly with a call to a function returning a vector, or explicitly by assigning the memory to a variable: |
||
< |
<syntaxhighlight lang="julia"> |
||
matrix = Array{Float64,2}(100,100) |
matrix = Array{Float64,2}(100,100) |
||
matrix[31,42] = pi |
matrix[31,42] = pi |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
Line 902: | Line 902: | ||
Some examples may help to make all this clear. In the interests of clarity, types have been specified for all variables though, in practice, this would be unnecessary in those cases where the variable's type can be inferred from the value assigned to it when it is declared. 'val' variables are read-only but 'var' variables are read/write. |
Some examples may help to make all this clear. In the interests of clarity, types have been specified for all variables though, in practice, this would be unnecessary in those cases where the variable's type can be inferred from the value assigned to it when it is declared. 'val' variables are read-only but 'var' variables are read/write. |
||
< |
<syntaxhighlight lang="scala">// version 1.1.2 |
||
class MyClass(val myInt: Int) { |
class MyClass(val myInt: Int) { |
||
Line 931: | Line 931: | ||
println(j) |
println(j) |
||
// 'j' becomes eligible for garbage collection here as no longer used |
// 'j' becomes eligible for garbage collection here as no longer used |
||
}</ |
}</syntaxhighlight> |
||
When this is run, notice that finalize() is not called - at least on my machine (running UBuntu 14.04, Oracle JDK 8): |
When this is run, notice that finalize() is not called - at least on my machine (running UBuntu 14.04, Oracle JDK 8): |
||
{{out}} |
{{out}} |
||
Line 945: | Line 945: | ||
=={{header|Lingo}}== |
=={{header|Lingo}}== |
||
Lingo does not allow direct memory allocation and has no direct access to memory types like heap, stack etc. But indirectly the ByteArray data type can be used to allocate memory that then later can be filled with custom data: |
Lingo does not allow direct memory allocation and has no direct access to memory types like heap, stack etc. But indirectly the ByteArray data type can be used to allocate memory that then later can be filled with custom data: |
||
< |
<syntaxhighlight lang="lingo">-- Create a ByteArray of 100 Kb (pre-filled with 0 bytes) |
||
ba = byteArray(102400) |
ba = byteArray(102400) |
||
-- Lingo uses garbage-collection, so allocated memory is released when no more references exist. |
-- Lingo uses garbage-collection, so allocated memory is released when no more references exist. |
||
-- For the above variable ba, this can be achieved by calling: |
-- For the above variable ba, this can be achieved by calling: |
||
ba = VOID</ |
ba = VOID</syntaxhighlight> |
||
=={{header|M2000 Interpreter}}== |
=={{header|M2000 Interpreter}}== |
||
Line 968: | Line 968: | ||
We can use Eval$(Mem1) to get a copy of a buffer in a string. |
We can use Eval$(Mem1) to get a copy of a buffer in a string. |
||
Statement Return used to place in many offsets data in one statement. |
Statement Return used to place in many offsets data in one statement. |
||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Module Checkit { |
Module Checkit { |
||
Buffer Clear Mem1 as Byte*12345 |
Buffer Clear Mem1 as Byte*12345 |
||
Line 982: | Line 982: | ||
} |
} |
||
Checkit |
Checkit |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Maple}}== |
=={{header|Maple}}== |
||
Line 988: | Line 988: | ||
You can allocate a large block of memory by creating an Array |
You can allocate a large block of memory by creating an Array |
||
< |
<syntaxhighlight lang="maple">a := Array( 1 .. 10^6, datatype = integer[1] ): |
||
</syntaxhighlight> |
|||
</lang> |
|||
Now you can use the storage in the Array assigned to <tt>a</tt> as you see fit. To ensure that <tt>a</tt> is garbage collected at the earliest opportunity, unassign the name <tt>a</tt>: |
Now you can use the storage in the Array assigned to <tt>a</tt> as you see fit. To ensure that <tt>a</tt> is garbage collected at the earliest opportunity, unassign the name <tt>a</tt>: |
||
<lang |
<syntaxhighlight lang="maple">unassign( a ):</syntaxhighlight> |
||
or |
or |
||
< |
<syntaxhighlight lang="maple">a := 'a':</syntaxhighlight> |
||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
Line 1,004: | Line 1,004: | ||
Matlab and Octave allocate memory when a new variable or a local variable is generated. Arrays are automatically extended as needed. However, extending the array might require to re-allocate the whole array. Therefore, pre-allocating memory can provide a significant performance improvement. |
Matlab and Octave allocate memory when a new variable or a local variable is generated. Arrays are automatically extended as needed. However, extending the array might require to re-allocate the whole array. Therefore, pre-allocating memory can provide a significant performance improvement. |
||
<syntaxhighlight lang="matlab"> |
|||
<lang MATLAB> |
|||
A = zeros(1000); % allocates memory for a 1000x1000 double precision matrix. |
A = zeros(1000); % allocates memory for a 1000x1000 double precision matrix. |
||
clear A; % deallocates memory |
clear A; % deallocates memory |
||
Line 1,012: | Line 1,012: | ||
b(k) = 5*k*k-3*k+2; |
b(k) = 5*k*k-3*k+2; |
||
end |
end |
||
</ |
</syntaxhighlight> |
||
=={{header|Maxima}}== |
=={{header|Maxima}}== |
||
< |
<syntaxhighlight lang="maxima">/* Maxima allocates memory dynamically and uses a garbage collector. |
||
Here is how to check available memory */ |
Here is how to check available memory */ |
||
Line 1,034: | Line 1,034: | ||
97138 pages available |
97138 pages available |
||
11399 pages in heap but not gc'd + pages needed for gc marking |
11399 pages in heap but not gc'd + pages needed for gc marking |
||
131072 maximum pages</ |
131072 maximum pages</syntaxhighlight> |
||
=={{header|Nanoquery}}== |
=={{header|Nanoquery}}== |
||
Even though the Nanoquery interpreter is implemented in Java, it is possible to use the native library to directly allocate and access memory located off the heap. In this example, 26 bytes are allocated, filled with the uppercase alphabet, then output to the console. Even though this code is running in the JVM, the allocated memory must still be freed at the end or a leak would occur. |
Even though the Nanoquery interpreter is implemented in Java, it is possible to use the native library to directly allocate and access memory located off the heap. In this example, 26 bytes are allocated, filled with the uppercase alphabet, then output to the console. Even though this code is running in the JVM, the allocated memory must still be freed at the end or a leak would occur. |
||
< |
<syntaxhighlight lang="nanoquery">import native |
||
// allocate 26 bytes |
// allocate 26 bytes |
||
Line 1,054: | Line 1,054: | ||
// free the allocated memory |
// free the allocated memory |
||
native.free(ptr)</ |
native.free(ptr)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>ABCDEFGHIJKLMNOPQRSTUVWXYZ</pre> |
<pre>ABCDEFGHIJKLMNOPQRSTUVWXYZ</pre> |
||
Line 1,060: | Line 1,060: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
Usually in Nim we have automated memory allocation and garbage collection, but we can still manually get a block of memory: |
Usually in Nim we have automated memory allocation and garbage collection, but we can still manually get a block of memory: |
||
< |
<syntaxhighlight lang="nim"># Allocate thread local heap memory |
||
var a = alloc(1000) |
var a = alloc(1000) |
||
dealloc(a) |
dealloc(a) |
||
Line 1,078: | Line 1,078: | ||
p = nil # set pointer to nil |
p = nil # set pointer to nil |
||
echo isNil(p) # true |
echo isNil(p) # true |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Objeck}}== |
=={{header|Objeck}}== |
||
In Objeck space for local variables is allocated when a method/function is called and deallocated when a method/function exits. Objects and arrays are allocated from the heap and their memory is managed by the memory manager. The memory manager attempts to collect memory when an allocation threshold is met or exceeded. The memory manger uses a mark and sweep [[Garbage collection|garbage collection]] algorithm. |
In Objeck space for local variables is allocated when a method/function is called and deallocated when a method/function exits. Objects and arrays are allocated from the heap and their memory is managed by the memory manager. The memory manager attempts to collect memory when an allocation threshold is met or exceeded. The memory manger uses a mark and sweep [[Garbage collection|garbage collection]] algorithm. |
||
< |
<syntaxhighlight lang="objeck">foo := Object->New(); // allocates an object on the heap |
||
foo_array := Int->New[size]; // allocates an integer array on the heap |
foo_array := Int->New[size]; // allocates an integer array on the heap |
||
x := 0; // allocates an integer on the stack</ |
x := 0; // allocates an integer on the stack</syntaxhighlight> |
||
=={{header|Oforth}}== |
=={{header|Oforth}}== |
||
Line 1,097: | Line 1,097: | ||
=={{header|OxygenBasic}}== |
=={{header|OxygenBasic}}== |
||
<lang> |
<syntaxhighlight lang="text"> |
||
'ALLOCATING MEMORY FROM DIFFERENT MEMORY SOURCES |
'ALLOCATING MEMORY FROM DIFFERENT MEMORY SOURCES |
||
Line 1,131: | Line 1,131: | ||
'MapViewOfFile |
'MapViewOfFile |
||
'UnmapViewOfFile |
'UnmapViewOfFile |
||
'CloseHandle</ |
'CloseHandle</syntaxhighlight> |
||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
All accessible memory in GP is on PARI's heap. Its size can be changed: |
All accessible memory in GP is on PARI's heap. Its size can be changed: |
||
<lang |
<syntaxhighlight lang="parigp">allocatemem(100<<20)</syntaxhighlight> |
||
to allocate 100 MB. |
to allocate 100 MB. |
||
Line 1,151: | Line 1,151: | ||
Dynamicly created objects (dynamic arrays, class instantiations, ...) are allocated on the heap.<br> |
Dynamicly created objects (dynamic arrays, class instantiations, ...) are allocated on the heap.<br> |
||
Their creation and destruction is done explicitly. |
Their creation and destruction is done explicitly. |
||
< |
<syntaxhighlight lang="pascal">type |
||
TByteArray = array of byte; |
TByteArray = array of byte; |
||
var |
var |
||
Line 1,159: | Line 1,159: | ||
... |
... |
||
setLength(A,0); |
setLength(A,0); |
||
end;</ |
end;</syntaxhighlight> |
||
< |
<syntaxhighlight lang="pascal">type |
||
Tcl = class |
Tcl = class |
||
dummy: longint; |
dummy: longint; |
||
Line 1,171: | Line 1,171: | ||
... |
... |
||
c1.destroy; |
c1.destroy; |
||
end;</ |
end;</syntaxhighlight> |
||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
Line 1,189: | Line 1,189: | ||
allocation routines (allocate and allocate_string) to automate that for you, or you could even roll your own via delete_routine(). |
allocation routines (allocate and allocate_string) to automate that for you, or you could even roll your own via delete_routine(). |
||
<!--< |
<!--<syntaxhighlight lang="phix">--> |
||
<span style="color: #004080;">atom</span> <span style="color: #000000;">addr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">512</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- limit is 1,610,612,728 bytes on 32-bit systems</span> |
<span style="color: #004080;">atom</span> <span style="color: #000000;">addr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">512</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- limit is 1,610,612,728 bytes on 32-bit systems</span> |
||
<span style="color: #0000FF;">...</span> |
<span style="color: #0000FF;">...</span> |
||
Line 1,195: | Line 1,195: | ||
<span style="color: #004080;">atom</span> <span style="color: #000000;">addr2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">512</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- automatically freed when addr2 drops out of scope or re-assigned</span> |
<span style="color: #004080;">atom</span> <span style="color: #000000;">addr2</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">512</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- automatically freed when addr2 drops out of scope or re-assigned</span> |
||
<span style="color: #004080;">atom</span> <span style="color: #000000;">addr3</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate_string</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"a string"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- automatically freed when addr3 drops out of scope or re-assigned</span> |
<span style="color: #004080;">atom</span> <span style="color: #000000;">addr3</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">allocate_string</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"a string"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- automatically freed when addr3 drops out of scope or re-assigned</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
Behind the scenes, the Phix stack is actually managed as a linked list of virtual stack blocks allocated on the heap, and as such it |
Behind the scenes, the Phix stack is actually managed as a linked list of virtual stack blocks allocated on the heap, and as such it |
||
Line 1,210: | Line 1,210: | ||
* On the stack: this happens with variables declared as automatic in procedures and begin blocks. The variables are automatically freed when at exit of the procedure or block. If an ''init'' clause is specified, the variable will also be (re-)initialized upon entry to the procedure or block. If no ''init'' clause is specified, the variable will most likely contain garbage. An example: |
* On the stack: this happens with variables declared as automatic in procedures and begin blocks. The variables are automatically freed when at exit of the procedure or block. If an ''init'' clause is specified, the variable will also be (re-)initialized upon entry to the procedure or block. If no ''init'' clause is specified, the variable will most likely contain garbage. An example: |
||
< |
<syntaxhighlight lang="pli"> |
||
mainproc: proc options(main) reorder; |
mainproc: proc options(main) reorder; |
||
Line 1,222: | Line 1,222: | ||
call subproc(); |
call subproc(); |
||
call subproc(); |
call subproc(); |
||
end mainproc;</ |
end mainproc;</syntaxhighlight> |
||
Result: |
Result: |
||
Line 1,230: | Line 1,230: | ||
* On the heap: if a variable is declared with the ''ctl'' (or in full, ''controlled'') attribute, it will be allocated from the heap and multiple generations of the same variable can exist, although only the last one allocated can be accessed directly. An example: |
* On the heap: if a variable is declared with the ''ctl'' (or in full, ''controlled'') attribute, it will be allocated from the heap and multiple generations of the same variable can exist, although only the last one allocated can be accessed directly. An example: |
||
< |
<syntaxhighlight lang="pli"> |
||
mainproc: proc options(main) reorder; |
mainproc: proc options(main) reorder; |
||
dcl ctlvar char ctl; |
dcl ctlvar char ctl; |
||
Line 1,247: | Line 1,247: | ||
put skip data(ctlvar); |
put skip data(ctlvar); |
||
free ctlvar; |
free ctlvar; |
||
end mainproc;</ |
end mainproc;</syntaxhighlight> |
||
Result: |
Result: |
||
Line 1,256: | Line 1,256: | ||
* On the heap: if a variable is declared with the ''based'' attribute, it will be allocated from the heap and multiple generations of the same variable can exist. This type of variable is often used in linked lists. An example: |
* On the heap: if a variable is declared with the ''based'' attribute, it will be allocated from the heap and multiple generations of the same variable can exist. This type of variable is often used in linked lists. An example: |
||
< |
<syntaxhighlight lang="pli"> |
||
mainproc: proc options(main) reorder; |
mainproc: proc options(main) reorder; |
||
dcl list_ptr ptr init (sysnull()); |
dcl list_ptr ptr init (sysnull()); |
||
Line 1,283: | Line 1,283: | ||
put skip list(list_data); |
put skip list(list_data); |
||
end; |
end; |
||
end mainprog;</ |
end mainprog;</syntaxhighlight> |
||
Result: |
Result: |
||
Line 1,292: | Line 1,292: | ||
=={{header|PureBasic}}== |
=={{header|PureBasic}}== |
||
< |
<syntaxhighlight lang="purebasic">*buffer=AllocateMemory(20) |
||
*newBuffer = ReAllocateMemory(*buffer, 2000) ;increase size of buffer |
*newBuffer = ReAllocateMemory(*buffer, 2000) ;increase size of buffer |
||
Line 1,306: | Line 1,306: | ||
; allocate an image for use with image functions |
; allocate an image for use with image functions |
||
CreateImage(1,size,size) |
CreateImage(1,size,size) |
||
FreeImage(1)</ |
FreeImage(1)</syntaxhighlight> |
||
Memory for strings is handled automatically from a separate memory heap. The automatic handling of string memory includes garbage collection and the freeing of string memory. |
Memory for strings is handled automatically from a separate memory heap. The automatic handling of string memory includes garbage collection and the freeing of string memory. |
||
Line 1,398: | Line 1,398: | ||
'''Example''' |
'''Example''' |
||
< |
<syntaxhighlight lang="python">>>> from array import array |
||
>>> argslist = [('l', []), ('c', 'hello world'), ('u', u'hello \u2641'), |
>>> argslist = [('l', []), ('c', 'hello world'), ('u', u'hello \u2641'), |
||
('l', [1, 2, 3, 4, 5]), ('d', [1.0, 2.0, 3.14])] |
('l', [1, 2, 3, 4, 5]), ('d', [1.0, 2.0, 3.14])] |
||
Line 1,412: | Line 1,412: | ||
array('l', [1, 2, 3, 4, 5]) |
array('l', [1, 2, 3, 4, 5]) |
||
array('d', [1.0, 2.0, 3.1400000000000001]) |
array('d', [1.0, 2.0, 3.1400000000000001]) |
||
>>></ |
>>></syntaxhighlight> |
||
=={{header|R}}== |
=={{header|R}}== |
||
< |
<syntaxhighlight lang="rsplus">x=numeric(10) # allocate a numeric vector of size 10 to x |
||
rm(x) # remove x |
rm(x) # remove x |
||
x=vector("list",10) #allocate a list of length 10 |
x=vector("list",10) #allocate a list of length 10 |
||
x=vector("numeric",10) #same as x=numeric(10), space allocated to list vector above now freed |
x=vector("numeric",10) #same as x=numeric(10), space allocated to list vector above now freed |
||
rm(x) # remove x</ |
rm(x) # remove x</syntaxhighlight> |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
Racket doesn't allow direct memory allocation, although it supports some things |
Racket doesn't allow direct memory allocation, although it supports some things |
||
< |
<syntaxhighlight lang="racket">#lang racket |
||
(collect-garbage) ; This function forces a garbage collection |
(collect-garbage) ; This function forces a garbage collection |
||
Line 1,434: | Line 1,434: | ||
; If amount of bytes can't be reached, <stop-custodian> is shutdown |
; If amount of bytes can't be reached, <stop-custodian> is shutdown |
||
(custodian-limit-memory <custodian> <amount>) ; Register a limit on memory for the <custodian></ |
(custodian-limit-memory <custodian> <amount>) ; Register a limit on memory for the <custodian></syntaxhighlight> |
||
Custodians manage threads, ports, sockets, etc. |
Custodians manage threads, ports, sockets, etc. |
||
Line 1,443: | Line 1,443: | ||
Like Perl 5, Raku is intended to run largely stackless, so all allocations are really on the heap, including activation records. Allocations are managed automatically. It is easy enough to allocate a memory buffer of a particular size however, if you really need it: |
Like Perl 5, Raku is intended to run largely stackless, so all allocations are really on the heap, including activation records. Allocations are managed automatically. It is easy enough to allocate a memory buffer of a particular size however, if you really need it: |
||
<lang |
<syntaxhighlight lang="raku" line>my $buffer = Buf.new(0 xx 1024);</syntaxhighlight> |
||
=={{header|Retro}}== |
=={{header|Retro}}== |
||
Retro's memory is directly accessible via '''fetch''' and '''store'''. This is used for all functions and data structures. A variable, '''Heap''', points to the next free address. '''allot''' can be used to allocate or free memory. The amount of memory varies by the runtime, and can be accessed via the '''EOM''' constant. |
Retro's memory is directly accessible via '''fetch''' and '''store'''. This is used for all functions and data structures. A variable, '''Heap''', points to the next free address. '''allot''' can be used to allocate or free memory. The amount of memory varies by the runtime, and can be accessed via the '''EOM''' constant. |
||
< |
<syntaxhighlight lang="retro">display total memory available |
||
~~~ |
~~~ |
||
Line 1,476: | Line 1,476: | ||
~~~ |
~~~ |
||
#-500 allot |
#-500 allot |
||
~~~</ |
~~~</syntaxhighlight> |
||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
Line 1,482: | Line 1,482: | ||
<br>Most REXX interpreters will obtain a chunk (block) of free storage, and then allocate storage out of that pool if possible, if not, obtain more storage. |
<br>Most REXX interpreters will obtain a chunk (block) of free storage, and then allocate storage out of that pool if possible, if not, obtain more storage. |
||
<br>One particular implementation of REXX has predefined and limited amount of free storage. |
<br>One particular implementation of REXX has predefined and limited amount of free storage. |
||
< |
<syntaxhighlight lang="rexx">Axtec_god.3='Quetzalcoatl ("feathered serpent"), god of learning, civilization, regeneration, wind and storms'</syntaxhighlight> |
||
There is no explicit way to de-allocate memory, but there is a DROP statement that "un-defines" a REXX variable and it's memory is then free to be used for other variables, provided that free memory isn't too fragmented. |
There is no explicit way to de-allocate memory, but there is a DROP statement that "un-defines" a REXX variable and it's memory is then free to be used for other variables, provided that free memory isn't too fragmented. |
||
< |
<syntaxhighlight lang="rexx">drop xyz NamesRoster j k m caves names. Axtec_god. Hopi Hopi |
||
/* it's not considered an error to DROP a variable that isn't defined.*/</ |
/* it's not considered an error to DROP a variable that isn't defined.*/</syntaxhighlight> |
||
Any variables (that are non-exposed) which are defined (allocated) in a procedure/subroutine/function will be un-allocated at the termination (completion, when it RETURNS or EXITs) of the procedure/subroutine/function. |
Any variables (that are non-exposed) which are defined (allocated) in a procedure/subroutine/function will be un-allocated at the termination (completion, when it RETURNS or EXITs) of the procedure/subroutine/function. |
||
<br><br> |
<br><br> |
||
=={{header|Ring}}== |
=={{header|Ring}}== |
||
< |
<syntaxhighlight lang="ring"> |
||
cVar = " " # create variable contains string of 5 bytes |
cVar = " " # create variable contains string of 5 bytes |
||
cVar = NULL # destroy the 5 bytes string ! |
cVar = NULL # destroy the 5 bytes string ! |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
Class#allocate explicitly allocates memory for a new object, inside the [[garbage collection|garbage-collected heap]]. Class#allocate never calls #initialize. |
Class#allocate explicitly allocates memory for a new object, inside the [[garbage collection|garbage-collected heap]]. Class#allocate never calls #initialize. |
||
< |
<syntaxhighlight lang="ruby">class Thingamajig |
||
def initialize |
def initialize |
||
fail 'not yet implemented' |
fail 'not yet implemented' |
||
end |
end |
||
end |
end |
||
t = Thingamajig.allocate</ |
t = Thingamajig.allocate</syntaxhighlight> |
||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
Line 1,511: | Line 1,511: | ||
https://github.com/rust-lang/rust/issues/32838 |
https://github.com/rust-lang/rust/issues/32838 |
||
< |
<syntaxhighlight lang="rust">// we have to use `unsafe` here because |
||
// we will be dereferencing a raw pointer |
// we will be dereferencing a raw pointer |
||
unsafe { |
unsafe { |
||
Line 1,527: | Line 1,527: | ||
// deallocate `ptr` with associated layout `int_layout` |
// deallocate `ptr` with associated layout `int_layout` |
||
dealloc(ptr, int_layout); |
dealloc(ptr, int_layout); |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
Line 1,536: | Line 1,536: | ||
If you want to allocate an arbitrary block of bytes that the interpreter will not interfere with, there are two ways to do it. The first is by altering the system variable <tt>RAMTOP</tt>: this is a 16-bit value stored in little-endian format at addresses 16388 and 16389, and tells BASIC the highest byte it can use. On a 1k ZX81, <tt>RAMTOP</tt> equals 17408 (until you change it); to find it on your system, use |
If you want to allocate an arbitrary block of bytes that the interpreter will not interfere with, there are two ways to do it. The first is by altering the system variable <tt>RAMTOP</tt>: this is a 16-bit value stored in little-endian format at addresses 16388 and 16389, and tells BASIC the highest byte it can use. On a 1k ZX81, <tt>RAMTOP</tt> equals 17408 (until you change it); to find it on your system, use |
||
<lang |
<syntaxhighlight lang="basic">PRINT PEEK 16388+256*16389</syntaxhighlight> |
||
You can then use <code>POKE</code> statements to reset <tt>RAMTOP</tt> to a lower value, thus reserving the space above it. |
You can then use <code>POKE</code> statements to reset <tt>RAMTOP</tt> to a lower value, thus reserving the space above it. |
||
The second approach, suitable especially if you want to reserve a few bytes for a small machine code subroutine, is to hide the storage space you want inside a comment. When you enter a <code>REM</code> statement, the interpreter sets aside sufficient bytes to store the text of your comment <i>and then doesn't care what you put in them</i>: if you know the address where the comment is stored, therefore, you can <code>POKE</code> whatever values you like into that space. If the comment is the first line in the program, the <code>REM</code> itself will be at address 16513 and the comment text will begin at 16514 and take up one byte per character. An example, with a trivial machine code routine (it adds 3 and 4): |
The second approach, suitable especially if you want to reserve a few bytes for a small machine code subroutine, is to hide the storage space you want inside a comment. When you enter a <code>REM</code> statement, the interpreter sets aside sufficient bytes to store the text of your comment <i>and then doesn't care what you put in them</i>: if you know the address where the comment is stored, therefore, you can <code>POKE</code> whatever values you like into that space. If the comment is the first line in the program, the <code>REM</code> itself will be at address 16513 and the comment text will begin at 16514 and take up one byte per character. An example, with a trivial machine code routine (it adds 3 and 4): |
||
< |
<syntaxhighlight lang="basic">10 REM ABCDEFGH |
||
20 LET P$="3E03010400814FC9" |
20 LET P$="3E03010400814FC9" |
||
30 LET ADDR=16514 |
30 LET ADDR=16514 |
||
Line 1,548: | Line 1,548: | ||
70 IF P$<>"" THEN GOTO 40 |
70 IF P$<>"" THEN GOTO 40 |
||
80 CLEAR |
80 CLEAR |
||
90 PRINT USR 16514</ |
90 PRINT USR 16514</syntaxhighlight> |
||
The <tt>ABCDEFGH</tt> is arbitrary: any other eight characters would work just as well. The string in line <tt>20</tt> is the hex representation of the Z80 code, which could be disassembled as: |
The <tt>ABCDEFGH</tt> is arbitrary: any other eight characters would work just as well. The string in line <tt>20</tt> is the hex representation of the Z80 code, which could be disassembled as: |
||
< |
<syntaxhighlight lang="z80asm">3e 03 ld a, 3 |
||
01 04 00 ld bc,0004 |
01 04 00 ld bc,0004 |
||
81 add a, c |
81 add a, c |
||
4f ld c, a |
4f ld c, a |
||
c9 ret</ |
c9 ret</syntaxhighlight> |
||
Line <tt>40</tt> reads a two-digit hex number and pokes its value into memory. <code>USR</code> ("user sub routine"), in line <tt>90</tt>, is a function that takes the address of a machine language routine, calls it, and returns the contents of the <tt>BC</tt> register pair when the routine terminates. Under normal circumstances, once you were satisfied the machine code program was working correctly you would remove lines <tt>20</tt> to <tt>80</tt>, leaving just the machine code subroutine and the call to it. Note that if you list the program once you have run it, the first line will look something like this: |
Line <tt>40</tt> reads a two-digit hex number and pokes its value into memory. <code>USR</code> ("user sub routine"), in line <tt>90</tt>, is a function that takes the address of a machine language routine, calls it, and returns the contents of the <tt>BC</tt> register pair when the routine terminates. Under normal circumstances, once you were satisfied the machine code program was working correctly you would remove lines <tt>20</tt> to <tt>80</tt>, leaving just the machine code subroutine and the call to it. Note that if you list the program once you have run it, the first line will look something like this: |
||
< |
<syntaxhighlight lang="basic">10 REM Y▀▀:▖ ▟?TAN</syntaxhighlight> |
||
Unfortunately, you cannot type that in directly: not all 256 possible values are accessible from the keyboard, so there is no point trying to learn to enter machine code in that form. |
Unfortunately, you cannot type that in directly: not all 256 possible values are accessible from the keyboard, so there is no point trying to learn to enter machine code in that form. |
||
Line 1,568: | Line 1,568: | ||
{{works with|Smalltalk/X}} |
{{works with|Smalltalk/X}} |
||
To allocate a non-movable, non garbage collected block of memory, eg. to hand out a block of memory on which an external C-function keeps a reference. The memory must be eventually explicitly freed by the programmer: |
To allocate a non-movable, non garbage collected block of memory, eg. to hand out a block of memory on which an external C-function keeps a reference. The memory must be eventually explicitly freed by the programmer: |
||
< |
<syntaxhighlight lang="smalltalk">handle := ExternalBytes new:size |
||
... |
... |
||
handle free</ |
handle free</syntaxhighlight> |
||
To allocate a non-movable block of memory, which is garbage collected as soon as the reference is no longer reachable by Smalltalk (to hand out a block of memory to an external function which does NOT keep a reference on it): |
To allocate a non-movable block of memory, which is garbage collected as soon as the reference is no longer reachable by Smalltalk (to hand out a block of memory to an external function which does NOT keep a reference on it): |
||
< |
<syntaxhighlight lang="smalltalk">handle := ExternalBytes unprotectedNew:size |
||
... |
... |
||
handle := nil "or no longer reachable" |
handle := nil "or no longer reachable" |
||
... |
... |
||
memory will be freed by the garbage collector eventually</ |
memory will be freed by the garbage collector eventually</syntaxhighlight> |
||
Of course, both are to be used with great care, as memory leaks are possible. Thus, it is only used by core parts of the system, eg. for async I/O buffers, shared memory, mapped I/O devices etc. Normal programs would not use them. |
Of course, both are to be used with great care, as memory leaks are possible. Thus, it is only used by core parts of the system, eg. for async I/O buffers, shared memory, mapped I/O devices etc. Normal programs would not use them. |
||
Line 1,583: | Line 1,583: | ||
In SNOBOL4, simple data values are just created and assigned to variables. Here, three separate strings are concatenated and stored as a newly allocated string variable: |
In SNOBOL4, simple data values are just created and assigned to variables. Here, three separate strings are concatenated and stored as a newly allocated string variable: |
||
< |
<syntaxhighlight lang="snobol4"> newstring = "This is creating and saving" " a new single string " "starting with three separate strings."</syntaxhighlight> |
||
Empty arrays are created by using the built-in function (the size is determined when it is created): |
Empty arrays are created by using the built-in function (the size is determined when it is created): |
||
< |
<syntaxhighlight lang="snobol4"> newarray = array(100)</syntaxhighlight> |
||
Empty tables are similarly created using the built-in function (new entries can be simply added at any later time by just storing them into the table): |
Empty tables are similarly created using the built-in function (new entries can be simply added at any later time by just storing them into the table): |
||
< |
<syntaxhighlight lang="snobol4"> newtable = table()</syntaxhighlight> |
||
User-defined datatypes (usually, multi-field structures) are defined using the data() built-in function (which creates the constructor and field access functions): |
User-defined datatypes (usually, multi-field structures) are defined using the data() built-in function (which creates the constructor and field access functions): |
||
< |
<syntaxhighlight lang="snobol4"> data("listnode(next,prev,datafield1,datafield2)")</syntaxhighlight> |
||
Then you allocate a new example of the defined listnode data item by using the constructor the data() function created: |
Then you allocate a new example of the defined listnode data item by using the constructor the data() function created: |
||
< |
<syntaxhighlight lang="snobol4"> newnode = listnode(,,"string data value1",17)</syntaxhighlight> |
||
The example thus created can be updated using the field access functions also created by the data() function: |
The example thus created can be updated using the field access functions also created by the data() function: |
||
< |
<syntaxhighlight lang="snobol4"> datafield1(newnode) = "updated data value 1"</syntaxhighlight> |
||
You don't need to explicitly de-allocate memory. When you leave a function which has declared local variables, data stored in those local variables is released upon return. You can also just store a null string into a variable, releasing the value that was stored in that variable previously: |
You don't need to explicitly de-allocate memory. When you leave a function which has declared local variables, data stored in those local variables is released upon return. You can also just store a null string into a variable, releasing the value that was stored in that variable previously: |
||
< |
<syntaxhighlight lang="snobol4"> newnode = </syntaxhighlight> |
||
SNOBOL4 automatically garbage collects released data items on an as-needed basis, and moves allocated items to consolidate all released space (so memory fragmentation is never a problem). You can explicitly garbage collect if you really want to: |
SNOBOL4 automatically garbage collects released data items on an as-needed basis, and moves allocated items to consolidate all released space (so memory fragmentation is never a problem). You can explicitly garbage collect if you really want to: |
||
<lang |
<syntaxhighlight lang="snobol4"> collect()</syntaxhighlight> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
Line 1,620: | Line 1,620: | ||
More commonly, a package written in [[C]] will be used to manage the memory on behalf of Tcl, with explicit memory management. Here is an example of such a package: |
More commonly, a package written in [[C]] will be used to manage the memory on behalf of Tcl, with explicit memory management. Here is an example of such a package: |
||
< |
<syntaxhighlight lang="c">#include <tcl.h> |
||
/* A data structure used to enforce data safety */ |
/* A data structure used to enforce data safety */ |
||
Line 1,814: | Line 1,814: | ||
/* Register the package */ |
/* Register the package */ |
||
return Tcl_PkgProvide(interp, "memalloc", "1.0"); |
return Tcl_PkgProvide(interp, "memalloc", "1.0"); |
||
}</ |
}</syntaxhighlight> |
||
The package would then be used like this: |
The package would then be used like this: |
||
< |
<syntaxhighlight lang="tcl">package require memalloc |
||
set block [memalloc 1000] |
set block [memalloc 1000] |
||
Line 1,824: | Line 1,824: | ||
someOtherCommand [memaddr $block] |
someOtherCommand [memaddr $block] |
||
puts "$block\[42\] is now [memget $block 42]" |
puts "$block\[42\] is now [memget $block 42]" |
||
memfree $block</ |
memfree $block</syntaxhighlight> |
||
Other methods of performing things like memory allocation are also possible. |
Other methods of performing things like memory allocation are also possible. |
||
Line 1,834: | Line 1,834: | ||
The only type of memory allocation where the programmer has any control is the initial number of elements of a List though even here additional elements can be allocated by simply adding them. |
The only type of memory allocation where the programmer has any control is the initial number of elements of a List though even here additional elements can be allocated by simply adding them. |
||
< |
<syntaxhighlight lang="ecmascript">// create a list with 10 elements all initialized to zero |
||
var squares = List.filled(10, 0) |
var squares = List.filled(10, 0) |
||
// give them different values and print them |
// give them different values and print them |
||
Line 1,842: | Line 1,842: | ||
squares.add(10 * 10) |
squares.add(10 * 10) |
||
System.print(squares) |
System.print(squares) |
||
squares = null // make eligible for GC </ |
squares = null // make eligible for GC </syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,853: | Line 1,853: | ||
This is a bare-bones implementation of a heap memory allocator for x86_64 Linux. We alloctate memory page at a time using brk and divide up the memory in chunks of requested size using a linked list-like block struct. Not optimized for speed or efficiency. |
This is a bare-bones implementation of a heap memory allocator for x86_64 Linux. We alloctate memory page at a time using brk and divide up the memory in chunks of requested size using a linked list-like block struct. Not optimized for speed or efficiency. |
||
< |
<syntaxhighlight lang="x86asm"> |
||
; linux x86_64 |
; linux x86_64 |
||
Line 1,959: | Line 1,959: | ||
ret |
ret |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|XPL0}}== |
=={{header|XPL0}}== |
||
< |
<syntaxhighlight lang="xpl0">int Array(10); \allocates 10 integers (40 bytes) of heap space |
||
Array2:= Reserve(10*4); \another way to allocate 10 integers of heap space |
Array2:= Reserve(10*4); \another way to allocate 10 integers of heap space |
||
Array3:= MAlloc(4); \allocate 4 paragraphs (64 bytes) of conventional memory |
Array3:= MAlloc(4); \allocate 4 paragraphs (64 bytes) of conventional memory |
||
... |
... |
||
Release(Array3); \release this memory so it can be used elsewhere</ |
Release(Array3); \release this memory so it can be used elsewhere</syntaxhighlight> |
||
Heap space (for 32-bit XPL0) resides in extended memory (on an |
Heap space (for 32-bit XPL0) resides in extended memory (on an |
||
Line 1,991: | Line 1,991: | ||
Extension libraries/DLLs (written in C) can add this capability (the FFI library does this). |
Extension libraries/DLLs (written in C) can add this capability (the FFI library does this). |
||
< |
<syntaxhighlight lang="zkl">Data(123); // this bit bucket expects hold 123 bytes |
||
List.createLong(123); // this list expects to hold 123 elements</ |
List.createLong(123); // this list expects to hold 123 elements</syntaxhighlight> |
||
=={{header|ZX Spectrum Basic}}== |
=={{header|ZX Spectrum Basic}}== |
||
Line 1,998: | Line 1,998: | ||
On the ZX Spectrum, memory above the ramtop is protected, so the usual way to reserve memory is to move the ramtop to a lower address using a clear command. The following example assumes that a 48k ZX Spectrum is being used: |
On the ZX Spectrum, memory above the ramtop is protected, so the usual way to reserve memory is to move the ramtop to a lower address using a clear command. The following example assumes that a 48k ZX Spectrum is being used: |
||
< |
<syntaxhighlight lang="zxbasic">10 REM This code is written for a 48k spectrum |
||
20 CLEAR 65535 - 8192: REM reserve 8192 bytes of memory |
20 CLEAR 65535 - 8192: REM reserve 8192 bytes of memory |
||
30 CLEAR 65535: REM unreserve the memory, moving the ramtop back to the top of the ram</ |
30 CLEAR 65535: REM unreserve the memory, moving the ramtop back to the top of the ram</syntaxhighlight> |
||
{{omit from|ACL2}} |
{{omit from|ACL2}} |