В C можно выделять динамические массивы с помощью malloc(sizeof(T) * N)
, а затем использовать арифметику указателей для получения элементов со смещением i в этом динамическом массиве.
В C ++ можно сделать то же самое, используя operator new()
так же, как malloc()
, а затем разместить new (например, можно увидеть решение для пункта 13 в книге Херба Саттера «Исключительный C ++: 47 инженерных головоломок, проблем программирования и решений») . Если у вас его нет, краткое изложение решения этого вопроса будет следующим:
T* storage = operator new(sizeof(T)*size);
// insert element
T* p = storage + i;
new (p) T(element);
// get element
T* element = storage[i];
Для меня это выглядело законным, поскольку я прошу кусок памяти с достаточным объемом памяти для хранения N выровненных элементов размером = sizeof(T)
. Поскольку sizeof(T)
должен возвращать размер элемента, который выровнен, и они размещаются один за другим в блоке памяти, использование арифметики указателей здесь нормально.
Однако затем мне указали на такие ссылки: http://eel.is/c++draft/expr.add#4 или http://eel.is/c++draft/intro.object#def:object и утверждая, что в C ++ operator new()
не возвращает объект массива, поэтому арифметика указателя над тем, что он вернул, и использование его в качестве массива является неопределенным поведением в отличие от ANSI C.
Я не настолько хорош в таких низкоуровневых вещах, и я действительно пытаюсь понять, читая это: https://www.ibm.com/developerworks/library/pa-dalign/ или это: http://jrruethe.github.io/blog/2015/08/23/Placement-new/, но я до сих пор не могу понять, был ли Саттер просто просто неправильно?
Я понимаю, что alignas
имеет смысл в таких конструкциях, как:
alignas(double) char array[sizeof(double)];
(c) http://georgeflanagin.com/alignas.php
Если кажется, что массив не находится в пределах double
(возможно, после char
в структуре, запущенной на 2-байтовом процессоре чтения).
Но это другое дело - я запросил память из кучи / свободного хранилища, особенно запросил оператор new для возврата памяти, которая будет содержать элементы, выровненные по sizeof(T)
.
Подводя итог, если это был TL; DR:
- Можно ли использовать
malloc()
для динамических массивов в C ++? - Можно ли использовать
operator new()
и новое размещение для динамических массивов в более старом C ++, в котором нет ключевого словаalignas
? - Не определено ли поведение арифметики указателя при использовании в памяти, возвращаемой
operator new()
? - Саттер советует код, который может сломаться на какой-нибудь старинной машине?
Извините, если это глупо.
(possibly-hypothetical)
из стандартной формулировки может быть извлечено некоторую выгоду? - person Galik   schedule 23.11.2018possibly-hypothetical
относится кhypothetical x[n]
после фактического массива, и квалификационныйif
из 4.2 также не использует его. - person   schedule 23.11.2018