Граничные теги: предотвращение нарушений доступа к памяти в однопользовательских системах непрерывного распределения памяти

Тег границы (n) может использоваться в однопользовательских системах непрерывного распределения памяти, чтобы предотвратить доступ программ к памяти или ее изменение за пределами выделенных границ.

В контексте распределения памяти система непрерывного выделения памяти относится к методу управления памятью, при котором программам выделяется память в непрерывном блоке памяти. Каждой программе назначается определенный диапазон адресов памяти, и важно следить за тем, чтобы программа не превышала выделенные ей границы и не обращалась к памяти, принадлежащей другим программам или операционной системе.

Для достижения этой цели одним из распространенных методов является использование граничных тегов. Граничный тег — это небольшой фрагмент метаданных, связанный с каждым выделенным блоком памяти. Обычно он находится непосредственно перед или после блока памяти и содержит информацию о размере и использовании блока.

Вот пример использования граничных тегов в C++:

#include <iostream>
// Structure representing a block of memory with boundary tags
struct MemoryBlock {
    size_t size;
    bool isAllocated;
    // Other data specific to your needs, such as program identifier, timestamp, etc.
    // ...
};
// Function to allocate memory with boundary tags
void* allocateMemory(size_t size) {
    // Allocate memory block with additional space for boundary tag
    MemoryBlock* block = static_cast<MemoryBlock*>(malloc(sizeof(MemoryBlock) + size));
    // Set the size and allocation status in the boundary tag
    block->size = size;
    block->isAllocated = true;
    // Return the pointer to the memory block (excluding the boundary tag)
    return static_cast<void*>(block + 1);
}
// Function to deallocate memory and update boundary tags
void deallocateMemory(void* ptr) {
    // Get the pointer to the boundary tag
    MemoryBlock* block = static_cast<MemoryBlock*>(ptr) - 1;
    // Update the allocation status in the boundary tag
    block->isAllocated = false;
    // Free the memory block (including the boundary tag)
    free(block);
}
int main() {
    // Allocate memory using the allocateMemory function
    int* numbers = static_cast<int*>(allocateMemory(5 * sizeof(int)));
    // Use the allocated memory
    for (int i = 0; i < 5; ++i) {
        numbers[i] = i + 1;
    }
// Deallocate the memory using the deallocateMemory function
    deallocateMemory(numbers);
    return 0;
}

В приведенном выше примере структура MemoryBlockпредставляет блок памяти с граничными тегами. При выделении памяти функция allocateMemoryвыделяет блок памяти с дополнительным пространством для граничного тега. Он устанавливает размер и статус распределения в теге границы.

При освобождении памяти функция deallocateMemoryобновляет статус выделения в граничном теге и освобождает блок памяти.

Используя граничные теги, программы могут гарантировать, что они останутся в пределах выделенной памяти. Если программа пытается получить доступ к памяти за ее пределами, ее можно обнаружить и обработать соответствующим образом, предотвращая ее вмешательство в работу других программ или системы.