История изменений
Исправление X512, (текущая версия) :
Так-то в любой программе ловить переполнение стэка не составляет труда.
GCC и Clang без дополнительных флагов не умеют корректно обрабатывать переполнение стека для больших массивов на стеке, возможно перепрыгивание защитной страницы и порча памяти перед блоком памяти стека.
Передать указатель на массив в стэке?
Нельзя. С указателями можно делать только две манипуляции: выделение памяти в куче со сборщиком мусора через NEW(ptr)
или присвоение другому указателю. Указатели в Обероне — это по сути идентификаторы объектов в куче. Чтобы делать адресную арифметику, надо использовать unsafe режим (IMPORT SYSTEM
).
Но можно передавать ссылки на что угодно в VAR-параметрах процедур. В случае массивов передаётся скрытый параметр длины массива если длина не указана в типе параметра.
MODULE A;
PROCEDURE Fill (VAR a: ARRAY OF INTEGER);
VAR i: INTEGER;
BEGIN
i := 0; WHILE i < LEN(a) DO
a[i] := -i;
INC(i) END;
END Fill;
PROCEDURE Do*;
VAR a: ARRAY 10000H OF INTEGER; (* вызывает $StackAlloc потому что есть вероятность перехода за защитную страницу *)
BEGIN
Fill(a);
HALT(0);
END Do;
END A.
(!) A.Do
Исходная версия X512, :
есть еще переполнение буфера, когда данные пишутся туда, где должны лежать адреса.
Так-то в любой программе ловить переполнение стэка не составляет труда.
GCC и Clang без дополнительных флагов не умеют корректно обрабатывать переполнение стека для больших массивов на стеке, возможно перепрыгивание защитной страницы и порча памяти перед блоком памяти стека.
Передать указатель на массив в стэке?
Нельзя. С указателями можно делать только две манипуляции: выделение памяти в куче со сборщиком мусора через NEW(ptr)
или присвоение другому указателю. Указатели в Обероне — это по сути идентификаторы объектов в куче. Чтобы делать адресную арифметику, надо использовать unsafe режим (IMPORT SYSTEM
).
Но можно передавать ссылки на что угодно в VAR-параметрах процедур. В случае массивов передаётся скрытый параметр длины массива если длина не указана в типе параметра.
MODULE A;
PROCEDURE Fill (VAR a: ARRAY OF INTEGER);
VAR i: INTEGER;
BEGIN
i := 0; WHILE i < LEN(a) DO
a[i] := -i;
INC(i) END;
END Fill;
PROCEDURE Do*;
VAR a: ARRAY 10000H OF INTEGER; (* вызывает $StackAlloc потому что есть вероятность перехода за защитную страницу *)
BEGIN
Fill(a);
HALT(0);
END Do;
END A.
(!) A.Do