Доступ на чтение последних 5 элементов

Могу ли я установить / отключить чтение (или запись) доступа к последним нескольким элементам обычного массива в C / C ++? Поскольку я не могу использовать память других процессов, я подозреваю, что это возможно, но как? Я погуглил, но не смог найти.

Если я могу, как?

Потому что я хочу попробовать что-то вроде этого:

SetPrivilage(arr,LAST_5_ELEMENTS,false);

try
{
for(int i=0;;i++) //without bound checking. i know its evil. just trying if it is possible
{
arr[i]++;     //array is 1-billion elements
}
}
catch(int catch_end_of_array)
{
printf("array-inc complete");
}

Memory:

|start of array |00|01|02|03|04|05|06|07|..|..|1B|start of protected page|xx|xx|xx|xx|xx|xx|xx|xx|xx|xx|xx|xx|xx|

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

-6

Решение

Я полагаю, ваш arr массив POD (простые старые данные) Вы можете сделать это в C ++ классом и перегрузить operator[] сделать проверку индекса времени выполнения.

Обычно вы не можете делать то, что хотите, и если бы вы могли, это сильно зависело бы от реализации и операционной системы.

В Linux разрешение на доступ к данным связано с виртуальная память отображение. Это связано с mmap (2) и munmap (2) с mprotect (2) системный вызов. Эти вызовы работают со степенью детализации на уровне страницы (размер страницы обычно составляет 4 КБ, а выравнивание — 4 КБ).

Вы могли бы сделать непослушные трюки, как mmapбольшой регион, mprotect его последней странице, и сделать арифметику непереносимого указателя для вычисления arr указатель. Это отвратительно, так что не делай этого. И ловить SIGSEGV с грязным mmapтрюки как это не очень портативный и, вероятно, не очень эффективный. И обработчик сигнала не может генерировать исключения C ++.

1

Другие решения

Это не может быть сделано переносимым способом и зависит от вашей операционной системы. Я подозреваю, что это нигде не возможно, поскольку защита памяти обычно работает на более грубом уровне (например, Linux имеет mprotect системный вызов, но это может защитить только весь pages (обычно 4k блоков), а не произвольные диапазоны.

3

Если вы защищаете страницу с помощью интерфейса операционной системы, вы можете расположить массив так, чтобы массив заканчивался там, где начинается защита. Вы должны были бы обозначить массив указателем, который вы установили (например, int *p), а не объявлять его как массив (например, int p[40]), потому что большинство реализаций C не дают вам способа указать адрес массива.

Из-за гранулярности защиты памяти большинства систем вы обычно можете выровнять только один конец массива с границей защиты. Так что это не очень полезный механизм для защиты границ массива. Я использовал его в целях тестирования, тестируя оба конца отдельно:

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

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

2