Memory access plugin

From SA-MP Wiki

Jump to: navigation, search

Contents

Memory access plugin

Memory access plugin
Plugin
AuthorBigETI
Released17/07/2013
Latest Versionv1.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.


Parameters:
(cells = 1)
cellsThe amount of cells to allocate (1 by default)


Return Values:

Returns a pointer to the allocated memory.


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.


Parameters:
(cells = 1)
cellsThe amount of cells to allocate (1 by default)


Return Values:

Returns a pointer to the allocated memory.


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.


Parameters:
(Pointer:pointer, cells = 1)
pointerA pointer to the allocated memory
cellsThe amount of cells to allocate (1 by default)


Return Values:

Returns a pointer to the re-allocated memory.


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.
MEM::free can be used aswell!


Parameters:
(Pointer:pointer)
pointerA pointer to the previosly allocated memory


Return Values:

Always returns true in fast mode In secure mode, it returns true after a success, otherwise false.


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!
Parameters:
(Pointer:pointer, index = 0)
pointerA pointer to the allocated memory
indexIndex of the memory block (0 by default)


Return Values:

The value from the memory


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!


Parameters:
(Pointer:pointer, index = 0, arr[], arr_size = sizeof arr)
pointerA pointer to the allocated memory
indexIndex of the memory block (0 by default)
arrArray to copy data to
arr_sizeArray size in cells


Return Values:

Returns the given pointer.


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!


Parameters:
(Pointer:pointer, index = 0, value)
pointerA pointer to the allocated memory
indexIndex of the memory block (0 by default)
valueValue to set


Return Values:

Returns the given value.


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!


Parameters:
(Pointer:pointer, index = 0, const data_arr[], arr_size = sizeof data_arr)
pointerA pointer to the allocated memory
indexIndex of the memory block (0 by default)
data_arrArray to copy
arr_sizeArray size in cells


Return Values:

The pointer of data_arr.


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!
Parameters:
(Pointer:dest, Pointer:src, len, dest_index = 0, src_index = 0)
destA pointer to the destination to copy
srcA pointer to copy data from
lenLenght of the memory block to copy
dest_indexIndex of the destination to copy (0 by default)
src_indexIndex of the source to copy from (0 by default)


Return Values:

The pointer of dest.


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!


Parameters:
(Pointer:pointer, size, index = 0)
pointerA pointer to the allocated memory
sizeSize of the memory block in cells
indexIndex of the memory block (0 by default)


Return Values:

The pointer of pointer.


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!


Parameters:
(&var)
varReference of the given variable.


Return Values:

The pointer of the reference.


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.


Parameters:
(Pointer:pointer, index = 0, cells = 2, MEM_E_sort_type:sort = MEM_E_sort_default)
pointerA pointer to the allocated memory
indexIndex of the memory block (0 by default)
cellsAmount of cells to mix (2 by default)
sortType of the sorting algorithm


Return Values:

Returns true after a success, otherwise false.


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:

Returns true after a success, otherwise false.


Parameters:
(Pointer:pointer, index = 0, cells = 2, mix_times = 5)
pointerA pointer to the allocated memory
indexIndex of the memory block (0 by default)
cellsAmount of cells to mix (2 by default)
mix_timesTimes to mix the data inside the block of memory (5 by default)


Return Values:

Returns true after a success, otherwise false.


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!


Parameters:
This function has no parameters.


Return Values:

Returns the address of the AMX.


Example Usage:

printf(" AMX pointer: 0x%x", MEM_amx_ptr());

MEM_is

Image:32px-Circle-style-warning.png

Important
Note

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!


Parameters:
(Pointer:pointer, index = 0)
pointerA pointer to the allocated memory
indexIndex of the memory block (0 by default)


Return Values:

Returns true if valid, otherwise false.


Example Usage:

printf(" Valid memory: %s", MEM_is(Pointer:1000)?("Yes"):("No"));

MEM_len

Image:32px-Circle-style-warning.png

Important
Note

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!


Parameters:
(Pointer:pointer)
pointerA pointer to the allocated memory


Return Values:

Returns the lenght of the allocated memory.


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

Image:32px-Circle-style-warning.png

Important
Note

Only available, if SECURE_MEMORY_PLUGIN has been defined, and only the secure plugin version being used.


Description:

  • MEM::result can be used aswell!


Parameters:
(bool:free_result = true)
free_resultFrees the result (true by default)


Return Values:

Returns the last result issued by one of the functions.


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:

MEM_EX::get_addr can be used aswell!


Parameters:
(variable->index)
variableA pointer to the allocated memory.
indexIndex of the memory block


Return Values:

Returns the address of the pointer and index.


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!


Parameters:
(pointer->index)
pointerA pointer to the allocated memory.
indexIndex of the memory block


Return Values:

Gets the value from an indexed pointer.


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!


Parameters:
(pointer->index)
pointerA pointer to the allocated memory.
indexIndex of the memory block


Return Values:

Calculates a pointer of a pointer and index.


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!


Parameters:
(size, indexed_iterator)
sizeSize of the memory block in cells
indexed_iteratorName of the indexed iterator (Declared by this macro)


Return Values:

This function does not return any specific 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!


Parameters:
(size, indexed_iterator)
sizeSize of the memory block in cells
indexed_iteratorName of the indexed iterator (Declared by this macro)


Return Values:

This function does not return any specific 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!


Parameters:
(pointer)
pointerA pointer to the allocated memory.


Return Values:

Returns the incremented pointer.


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!


Parameters:
(pointer)
pointerA pointer to the allocated memory.


Return Values:

Returns the decremented pointer.


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:

0


MEM_MACR_NULL

Description:

  • MEM_EX::NULL can be used aswell!
  • Only defined, if MEM_NULL_EX is defined aswell!


Return Values:

0


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:

4


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

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
Personal tools