Ответы, которые я получил по этому вопросу, до сих пор имеют два противоположных ответа: "это безопасно" и "это поведение undefined". Я решил переписать вопрос в целом, чтобы получить более четкие ответы, для меня и для тех, кто может приехать сюда через Google.
Кроме того, я удалил тег C
, и теперь этот вопрос задан как С++
Я делаю 8-байт-выровненную кучу памяти, которая будет использоваться в моей виртуальной машине. Самый очевидный подход, о котором я могу думать, - это выделить массив std::uint64_t
.
std::unique_ptr<std::uint64_t[]> block(new std::uint64_t[100]);
Предположим sizeof(float) == 4
и sizeof(double) == 8
. Я хочу сохранить float и double в block
и напечатать значение.
float* pf = reinterpret_cast<float*>(&block[0]);
double* pd = reinterpret_cast<double*>(&block[1]);
*pf = 1.1;
*pd = 2.2;
std::cout << *pf << std::endl;
std::cout << *pd << std::endl;
Я также хотел бы сохранить C-строку с надписью "привет".
char* pc = reinterpret_cast<char*>(&block[2]);
std::strcpy(pc, "hello\n");
std::cout << pc;
Теперь я хочу сохранить "Привет, мир!". который превышает 8 байтов, но я все еще могу использовать две последовательные ячейки.
char* pc2 = reinterpret_cast<char*>(&block[3]);
std::strcpy(pc2, "Hello, world\n");
std::cout << pc2;
Для целых чисел мне не нужен reinterpret_cast
.
block[5] = 1;
std::cout << block[5] << std::endl;
Я выделяю block
как массив std::uint64_t
для единственной цели выравнивания памяти. Я также не ожидаю, что в нем будет храниться больше 8 байтов. Тип блока может быть любым, если начальный адрес гарантированно выравнивается по 8 байт.
Некоторые люди уже ответили, что то, что я делаю, абсолютно безопасно, но некоторые другие сказали, что я определенно вызываю поведение undefined.
Я пишу правильный код, чтобы делать то, что намерен? Если нет, то каким образом?