Memory access plugin
From SA-MP Wiki
Contents |
Memory access plugin
Memory access plugin Plugin | |
---|---|
Author | BigETI |
Released | 17/07/2013 |
Latest Version | v1.1.1 (17/07/2013) |
Development Status | Active |
License | Mozilla Public License |
Forum Topic |
General info
About
This plugin allows you to allocate dynamic memory, use it, and free it after you don't want to use it anymore.
Why?
PAWN literally doesn't allow you to manage dynamic memory at all. But still there has been releases such as for example y_malloc, which allows you to use dynamic memory in your PAWN scripts. Speed comparison between y_malloc and this plugin can be found here:
Allow your scripts to shrink their AMX sizes, by using dynamic memory.
Dangerous sides
Be aware of this release. It allows you to easily mess around with your machine. This release can give more and more headaches over time, if you don't know what you are trying to do!
Memory leak
new Pointer:my_memory = MEM::malloc(5); // Allocate 20 bytes memory (because 5 x 4 bytes) my_memory = Pointer:NULL; // You'll loose the reference to your memory
You've just lost the reference to the dynamicly allocated memory. This memory still exists, but it becomes totally useless. Your OS will probably keep track of the memory and claim it back after the application has finished. But on some special systems leaking memory won't be claimed back at all!
Memory fragmentation
new Pointer:mem1 = MEM::malloc(5), Pointer:mem2 = MEM::malloc(5), Pointer:mem3 = MEM::malloc(5), Pointer:mem4 = MEM::malloc(5), Pointer:mem5 = MEM::malloc(5); MEM::free(mem2); MEM::free(mem4); mem2 = MEM::malloc(10); // Can't be allocated at its same place anymore
As you can see we allocate 5 cells 5 times and free memory at mem2 and mem4. The new allocated memory (10 cells) can't fit into those free'd memories. You'll practically loose useful memory in runtime.
Accessing bad memory
MEM::get_val(Pointer:1, _, 1234); // Trying to set a value into non allocated memory
Process and memory share the same hardware in your machine. If you attempt to read or manipulate bad memory, your application will get errors and crashes.
Using null pointer to access memory
new Pointer:some_pointer = MEM::malloc(0xFFFFFFFF); // This pointer can get zero due it wasn't able to allocate that amount of memory MEM::set_val(some_pointer, _, 0xFFFFFFFF); // Crashes your application, if "some_pointer" equals Pointer:0
It still belongs to accessing bad memory, but in this case you are not able to allocate that amount of memory and MEM::malloc returns Pointer:0. To detect this, you should use this step:
new Pointer:some_pointer = MEM::malloc(0xFFFFFFFF); if(some_pointer) { // Good pointer } else { // Null pointer, handle error }
Out of bounds
new Pointer:mem = MEM::malloc(2); MEM::set_val(mem, 100, 10); // Obviosly accessing memory out of bounds MEM::set_val(mem, -1, 10); // Accessing over negative index, still out of bounds
By using indexes greater or equal allocated size accesses memory out of bounds. Of course accessing memory using negative indexes causes you to access memory out of bounds.
Documentation
Natives
MEM_malloc
Description:
- Allocates uninitialized dynamic memory to use.
- MEM::malloc can be used aswell!
- Always use MEM_free or MEM::free to free previously allocated memory.
cells | The amount of cells to allocate (1 by default) |
Return Values:
Example Usage:
new Pointer:mem = MEM_malloc(2); // Allocates 8 bytes. ( Allocates 4 bytes by default. ) if(mem) { // Valid // ... // Free memory MEM_free(mem); } else { // Error }
MEM_calloc
Description:
- Allocates zero set memory to use.
- MEM::calloc can be used aswell!
- Always use MEM_free or MEM::free to free previously allocated memory.
cells | The amount of cells to allocate (1 by default) |
Return Values:
Example Usage:
new Pointer:mem = MEM_calloc(2); // Allocates 8 bytes. ( Allocates 4 bytes by default. ) if(mem) { // Valid // ... // Free memory MEM_free(mem); } else { // Error }
MEM_realloc
Description:
- Re-allocates memory to use.
- MEM::realloc can be used aswell!
- Always use MEM_free or MEM::free to free previously allocated memory.
pointer | A pointer to the allocated memory |
cells | The amount of cells to allocate (1 by default) |
Return Values:
Example Usage:
new Pointer:mem = MEM_malloc(2); // Allocates 8 bytes. ( Allocates 4 bytes by default. ) if(mem) { // Valid new new_mem = MEM_realloc(mem, 5) // Re-allocates 20 bytes. ( Re-allocates 4 bytes by default. ) if(new_mem) { // Valid // "mem" is now invalid mem = Pointer:NULL; // ... MEM_free(new_mem); } else { // Error // ... // Free memory MEM_free(mem); } } else { // Error }
MEM_free
Description:
- Frees previously allocated memory.
pointer | A pointer to the previosly allocated memory |
Return Values:
Example Usage:
new Pointer:mem = MEM_malloc(2); // Allocates 8 bytes. ( Allocates 4 bytes by default. ) if(mem) { // Valid // ... // Free memory MEM_free(mem); } else { // Error }
MEM_get_val
{{Description|
- Gets the value from an allocated memory.
- MEM::get_val can be used aswell!
pointer | A pointer to the allocated memory |
index | Index of the memory block (0 by default) |
Return Values:
Example Usage:
new Pointer:mem = MEM_malloc(); // Allocates 4 bytes by default if(mem) { // Valid // Get the value using a pointer printf("Value: %d", MEM_get_val(mem)); // ... // Free memory MEM_free(mem); } else { // Error }
MEM_get_arr
Description:
- Gets an array of data from an allocated memory.
- MEM::get_arr can be used aswell!
pointer | A pointer to the allocated memory |
index | Index of the memory block (0 by default) |
arr | Array to copy data to |
arr_size | Array size in cells |
Return Values:
Example Usage:
// My array new my_array[10]; // Allocate 40 bytes (10 cells) new Pointer:mem = MEM_malloc(sizeof my_array); if(mem) { // Valid // Get an array of data using a pointer and size MEM_get_arr(mem, _, my_array); // ... // Free memory MEM_free(mem); } else { // Error }
MEM_set_val
Description:
- Sets a value in an allocated memory.
- MEM::set_val can be used aswell!
pointer | A pointer to the allocated memory |
index | Index of the memory block (0 by default) |
value | Value to set |
Return Values:
Example Usage:
// Allocates 4 bytes by default new Pointer:mem = MEM_malloc(); if(mem) { // Valid // Set the value using a pointer MEM_set_val(mem, _, 100); //... // Free memory MEM_free(mem); } else { // Error }
MEM_set_arr
Description:
- Sets an array of data into an allocated memory.
- MEM::set_arr can be used aswell!
pointer | A pointer to the allocated memory |
index | Index of the memory block (0 by default) |
data_arr | Array to copy |
arr_size | Array size in cells |
Return Values:
Example Usage:
// My constant array new const my_array[10] = {100, ...}; // Allocates 40 bytes (Allocates 4 bytes by default) new Pointer:mem = MEM_malloc(sizeof my_array); if(mem) { // Valid // Copy the array of data using a pointer and size MEM_set_arr(mem, _, my_array); //... // Free memory MEM_free(mem); } else { // Error }
MEM_copy
{{Description|
- Copies blocks of data from one address to another address.
- MEM::copy can be used aswell!
dest | A pointer to the destination to copy |
src | A pointer to copy data from |
len | Lenght of the memory block to copy |
dest_index | Index of the destination to copy (0 by default) |
src_index | Index of the source to copy from (0 by default) |
Return Values:
Example Usage:
// My constant array new const my_array[] = {1, 2, 3, 4, 5}; // Allocates 16 bytes (Allocates 4 bytes by default) new Pointer:mem1 = malloc(sizeof my_array); if(mem1) { // Valid // Allocates 16 bytes (Allocates 4 bytes by default) new Pointer:mem2 = malloc(sizeof my_array); if(mem2) { // Valid // Set the array of data using a pointer and size MEM_set_arr(mem1, _, my_array); // Copy blocks of data to "mem2" MEM_copy(mem2, mem1, sizeof my_array); // ... // Free memory MEM_free(mem2); } else { // Error } // ... // Free memory MEM_free(mem1); } else { // Error }
MEM_zero
Description:
- Zero sets memory
- MEM::zero can be used aswell!
pointer | A pointer to the allocated memory |
size | Size of the memory block in cells |
index | Index of the memory block (0 by default) |
Return Values:
Example Usage:
// Allocates 40 bytes (Allocates 4 bytes by default) Pointer:mem = malloc(10); if(mem) { // Valid // Zero sets memory MEM_zero(mem, 10); // ... // Free memory MEM_free(mem); } else { // Error }
MEM_get_addr
Description:
- Gets the pysical address of a PAWN sided variable.
- MEM::get_addr can be used aswell!
var | Reference of the given variable. |
Return Values:
Example Usage:
new my_var; printf("my_var address: 0x%x", _:MEM_get_addr(my_var));
MEM_sort
Description:
- Sorts the values inside the block of memory.
- MEM::sort can be used aswell!
- Sorts by ascending order by using MEM_E_sort_default.
- Sorts by descending order by using MEM_E_sort_reverse.
pointer | A pointer to the allocated memory |
index | Index of the memory block (0 by default) |
cells | Amount of cells to mix (2 by default) |
sort | Type of the sorting algorithm |
Return Values:
Example Usage:
// Allocates 16 bytes (Allocates 4 bytes by default) new Pointer:mem = MEM_malloc(4); if(mem) { // Valid // Set data MEM_set_arr(mem, _, {2, 5, 8, 3}); // Sort data by ascending order MEM_sort(mem, _, 4); // Sort data by descending order MEM_sort(mem, _, 4, MEM_E_sort_reverse); // ... // Free memory MEM_free(mem); } else { // Error }
MEM_mix
Description:
- Mixes the values inside the block of memory.
- MEM::mix can be used aswell!
- Mixes randomly by using a mix algorithm.
- Mixes data 5 times by default.
Return Values:
pointer | A pointer to the allocated memory |
index | Index of the memory block (0 by default) |
cells | Amount of cells to mix (2 by default) |
mix_times | Times to mix the data inside the block of memory (5 by default) |
Return Values:
Example Usage:
// Allocates 16 bytes (Allocates 4 bytes by default) new Pointer:mem = MEM_malloc(4); if(mem) { // Valid // Set data MEM_set_arr(mem, _, {2, 3, 4, 5}); // Mix data randomly MEM_mix(mem, _, 4); // ... // Free memory MEM_free(mem); } else { // Error }
MEM_amx_ptr
Description:
- Returns the pointer of the current AMX.
- MEM::amx_ptr can be used aswell!
Return Values:
Example Usage:
printf(" AMX pointer: 0x%x", MEM_amx_ptr());
MEM_is
Important | Only available, if SECURE_MEMORY_PLUGIN has been defined, and only the secure plugin version being used. |
Description:
- Checks, if the pointer and index are valid.
- MEM::is can be used aswell!
pointer | A pointer to the allocated memory |
index | Index of the memory block (0 by default) |
Return Values:
Example Usage:
printf(" Valid memory: %s", MEM_is(Pointer:1000)?("Yes"):("No"));
MEM_len
Important | Only available, if SECURE_MEMORY_PLUGIN has been defined, and only the secure plugin version being used. |
Description:
- Returns the lenght of the allocated memory.
- MEM::len can be used aswell!
pointer | A pointer to the allocated memory |
Return Values:
Example Usage:
// Allocates 20 bytes (Allocates 4 bytes by default) new Pointer:mem = malloc(5); if(mem) { // Prints the lenght of the allocated memory (5 cells) printf(" Memory lenght: %d", MEM_len(mem)); // ... // Free memory MEM_free(mem); } else { // Error }
MEM_result
Important | Only available, if SECURE_MEMORY_PLUGIN has been defined, and only the secure plugin version being used. |
Description:
- MEM::result can be used aswell!
free_result | Frees the result (true by default) |
Return Values:
Example Usage:
// Allocates 40 bytes (Allocates 4 bytes by default) new Pointer:mem = malloc(10); // Shows the last result printf("Result ID: %d", _:MEM_result()); if(mem) { // ... // Free memory MEM_free(mem); } else { // Error }
Macros
MEM_MACR_get_addr
Description:
variable | A pointer to the allocated memory. |
index | Index of the memory block |
Return Values:
Example Usage:
new my_array[5]; printf(" my_array[4] address: 0x%x", MEM_MACR_get_addr(my_array[0]->4));
MEM_MACR_get_val
Description:
- MEM_EX::get_val can be used aswell!
pointer | A pointer to the allocated memory. |
index | Index of the memory block |
Return Values:
Example Usage:
new Pointer:mem = MEM_malloc(5); // Allocate 20 bytes if(mem) { // Valid printf(" Value: %d", MEM_MACR_get_val(mem->4)); // Get indexed value MEM_free(mem); } else { // Error }
MEM_MACR_get_ptr
Description:
- MEM_EX::get_ptr can be used aswell!
pointer | A pointer to the allocated memory. |
index | Index of the memory block |
Return Values:
Example Usage:
// Allocates 20 bytes (Allocates 4 bytes by default) new Pointer:mem = MEM_malloc(5); if(mem) { // Valid // Get pointer by index printf(" Pointer: 0x%x", _:MEM_MACR_get_ptr(mem->4)); // ... // Free memory MEM_free(mem); } else { // Error }
MEM_MACR_foreach
Description:
- Loops through indexes using size and allocating an indexed iterator to use. (ascending)
- MEM_EX::foreach can be used aswell!
- Do NOT allocate an indexed iterator by yourself. The macro will do it for you automaticly to use!
size | Size of the memory block in cells |
indexed_iterator | Name of the indexed iterator (Declared by this macro) |
Return Values:
Example Usage:
// Allocates 20 bytes (Allocates 4 bytes by default) new Pointer:mem = MEM_malloc(5); if(mem) { // Valid // Iterate through data ascending MEM_MACR_foreach(5, mem_i) { // Prints value by index printf(" Value: %d", MEM_get_val(mem, mem_i)); } // ... // Free memory MEM_free(mem); } else { // Error }
MEM_MACR_foreach_rev
Description:
- Loops through indexes using size and allocating an indexed iterator to use. (descending)
- MEM_EX::foreach_rev can be used aswell!
- Do NOT allocate an indexed iterator by yourself. The macro will do it for you automaticly to use!
size | Size of the memory block in cells |
indexed_iterator | Name of the indexed iterator (Declared by this macro) |
Return Values:
Example Usage:
// Allocates 20 bytes (Allocates 4 bytes by default) new Pointer:mem = MEM_malloc(5); if(mem) { // Valid // Iterate through data ascending MEM_MACR_foreach_rev(5, mem_i) { // Prints value by index printf(" Value: %d", MEM_get_val(mem, mem_i)); } // ... // Free memory MEM_free(mem); } else { // Error }
MEM_MACR_increment_ptr
Description:
- Increments a pointer properly
- MEM_EX::increment_ptr can be used aswell!
pointer | A pointer to the allocated memory. |
Return Values:
Example Usage:
// Prints "Pointer: 8" printf(" Pointer: %d", _:MEM_MACR_increment(Pointer:4));
MEM_MACR_decrement_ptr
Description:
- Decrements a pointer properly
- MEM_EX::decrement_ptr can be used aswell!
pointer | A pointer to the allocated memory. |
Return Values:
Example Usage:
// Prints "Pointer: 0" printf(" Pointer: %d", _:MEM_MACR_increment(Pointer:4));
Definitions
SECURE_MEMORY_PLUGIN
Description:
- If defined, the include will ONLY work for the secure plugin version.
NULL
Description:
- Not defined, if MEM_NULL_EX is defined!
Return Values:
MEM_MACR_NULL
Description:
- MEM_EX::NULL can be used aswell!
- Only defined, if MEM_NULL_EX is defined aswell!
Return Values:
MEM_struct
Description:
- Used to create structs
- MEM::struct can be used aswell!
Example Usage:
MEM_struct my_struct { item_1, item_2[10], item_3 }
MEM_MACR_SIZEOF_CELL
Description:
- MEM_EX::SIZEOF_CELL[/B] can be used aswell!
Return Values:
Enumerators
MEM_E_sort_type
Description:
- MEM_E::res can be used aswell!
Items:
- MEM_E_res_ok or MEM_E::res_ok
- MEM_E_res_no_alloc or MEM_E::res_no_alloc
- MEM_E_res_inv_ptr or MEM_E::res_inv_ptr
- MEM_E_res_neg_index or MEM_E::res_neg_index
- MEM_E_res_inv_index or MEM_E::res_inv_index
- MEM_E_res_null_arr or MEM_E::res_null_arr
- MEM_E_res_inv_size or MEM_E::res_inv_size
- MEM_E_res_inv_op or MEM_E::res_inv_op
Setup
Put the plugin binary into your server's plugins folder and set in server.cfg
Windows:
plugins memory
LINUX:
plugins memory.so
After that you can use the memory include in your scripts:
// On top of your script #include <memory> // your code
Compile and run.
Alternatively you can use the secure version (which is wastly slower):
Windows:
plugins memory_secure
LINUX:
plugins memory_secure.so
Of course you can use the memory include in your scripts:
// On top of your script #define SECURE_MEMORY_PLUGIN #include <memory> // your code
Compile and run.
Downloads
- memory.dll, memory_secure.dll (Win32), memory.inc
- memory.so, memory_secure.so (Ubuntu 14.01 LTS), memory.inc
- memory.so, memory_secure.so (Debian 7 Wheezy), memory.inc
- (Source files)
Changelog
- v1.1.1 -> Code optimization ( 19.10.2015 )
- v1.1 -> Added MEM_copy, MEM_zero, MEM_E_res (secure only), MEM_is (secure only), MEM_len (secure only), and MEM_result (secure only) ( 17.10.2013 )
- v1.0.01 -> Updated SDK and changed the includes ( 17.07.2013 )
- v1.0 -> Initial release ( 17.07.2013 )
Credits
- BigETI
Programming Creating http://forum.sa-mp.com/showthread.php?t=451381 Compiling for Win32 and Ubuntu 14.01 LTS
- Bluescreen
Compiling for Debian 7 (Wheezy)
- SA:MP Development Team
SDK
- Y_Less
For the speed comparison idea
Thanks for their previous support:
- Mellnik
- Markā¢
- Tenshi
- leonardo1434
- Josstaa