Можно ли использовать один вызов malloc для выделения двух массивов? - PullRequest
2 голосов
/ 22 октября 2019

Если я знаю, что тоже типы T и U имеют одинаковое выравнивание, могу ли я использовать один вызов malloc следующим образом:

void* allocate_memory(int n, int m) {
  return malloc(sizeof(T) * n + sizeof(U) * m);
}

, чтобы выделить непрерывную память для массивов этих двух типов?

Если все в порядке, как правильно получить указатель на первый элемент второго массива? Преобразование void * -> char * -> (+ = sizeof (T) * n) -> U * выглядит нормально, но я чувствую, что там может быть какое-то неопределенное поведение.

(япочти уверен, что это не может быть сделано в C ++, правила арифметики с указателями этого не позволят (ни в одном случае массив U не начинает существовать, поэтому вы не можете выполнять арифметику с указателями в этом хранилище). Отсюда моя осторожность в отношении правил C)

1 Ответ

3 голосов
/ 22 октября 2019

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

Если p - возвращенный указатель, (U *)((char *)p + sizeof(T) * n) - действительный указатель на то, что вы хотите.

Обратите внимание, что вы можете избавиться от требования "одинакового выравнивания", просто используя _Alignof(U) или используя sizeof(U) (или наибольшую степень двух, которая делит его) в качестве (не обязательно точной) оценки для выравнивания и работы. между необходимыми отступами, чтобы достичь кратности выравнивания. Если вы сделаете это, убедитесь, что правильно распределили общую сумму, включая отступы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...