С точки зрения Стандарта, попытка выделить VLA с размером, который реализация не может вместить, вызывает Undefined Behavior. Поскольку стандарт не предоставляет средств для определения того, какой размер массива может безопасно создать реализация, и не требует, чтобы реализации допускали какой-либо конкретный размер, любая попытка создать объект VLA с размером больше 1 должна рассматриваться как вызов неопределенного поведения, за исключением случаях, когда кто-то знает достаточно о внутренней работе реализации, чтобы определить размер VLA, с которым он сможет справиться.
Если malloc() недоступен, лучше всего определить большой массив любого типа с самым грубым требованием выравнивания, сохранить его адрес в указателе с квалификацией volatile
[хранилище, в котором находится сам указатель, должно быть квалифицировано таким образом] читать обратно и интерпретировать это как начало пула памяти. Никакое другое использование исходного объекта массива не допускается. Хотя стандарт не гарантирует, что компилятор не решит, что он должен генерировать код, который проверяет, идентифицирует ли указатель исходный объект, и, если это так, пропускает любой код, который будет использовать этот указатель для доступа к чему-либо, кроме исходного типа объекта, использование volatile
в указателе должно сделать это маловероятным.
После создания пула памяти вы можете написать свои собственные функции управления памятью, чтобы использовать его, хотя каждый раз, когда указатель возвращается в пул, может потребоваться использовать хак volatile
-отмывания указателя, чтобы компиляторы не использовали тип- на основе псевдонимов, чтобы оправдать обработку последнего использования хранилища как его старого типа как неупорядоченного по сравнению с первым использованием хранилища как нового типа.
person
supercat
schedule
09.01.2017