Приведение массива символов без знака к длинному длинному [закрыто]

StackOverflow https://stackoverflow.com//questions/21048578

Вопрос

Я не уверен, правильно ли это, я проверил и кажется, что некоторые байты отключены...В принципе, у меня есть следующее:

unsigned char szBuffer[1024] = {0};
long long nValue = 1334553536;
memcpy(szBuffer, (char*)&nValue, sizeof(long long));

//

long long nNewValue = reinterpret_cast<long long>(szBuffer);
printf(nNewValue); //prints out a smaller number than previously stated

Кто-нибудь возражает указать, где я ошибся?Спасибо.

Это было полезно?

Решение

Вы устанавливаете nNewValue по адресу szBuffer, вместо чтения данных с этого адреса.Использовать:

long long nNewValue = *reinterpret_cast<long long*>(szBuffer);

Другие советы

Изменить это утверждение

long long nNewValue = reinterpret_cast<long long>(szBuffer);
.

к

long long nNewValue = *reinterpret_cast<long long *>(szBuffer);
.

Вот измененная версия вашей программы, которая работает в моей системе (расширено до полной программы):

#include <iostream>
#include <cstring>
int main() {
    unsigned char szBuffer[1024] = {0};
    long long nValue = 1334553536;
    std::memcpy(szBuffer, &nValue, sizeof(long long));
    long long nNewValue = *(reinterpret_cast<long long*>(&szBuffer));
    std::cout << nValue << "\n" << nNewValue << "\n";
}

memcpyпервые два параметра имеют тип void*, так что вам не нужно их разыгрывать;если вы приведете их (это преобразование устарело в C ++?), вы должны привести к void*, не char*.

Назначение на nNewValue преобразует адрес из буфера в long long*, а затем разыменовывает преобразованное значение.

Но это плохая идея.g ++ выдает мне предупреждение о разыменовании преобразованного указателя:

warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]

Кроме того, нет никакой гарантии, что szBuffer, который представляет собой массив unsigned char, правильно выровнен , так что его первые несколько байтов можно безопасно рассматривать как long long объект.Система x86 или x86_64, которую вы, скорее всего, используете, допускает несогласованный доступ к памяти, но не все системы делают это.

Приведение указателей часто небезопасно, если вы не знаете именно так то, что ты делаешь.

Если вы хотите переосмыслить часть массива символов как объект какого-либо другого типа, вы можете использовать объединение, если вам действительно нужно интерпретировать саму память как объект другого типа, или использовать memcpy.(Тем не менее, будьте уверены, что вам действительно нужно это сделать;вполне вероятно, что вы этого не делаете.Большую часть времени, если вы хотите сохранить long long возражаете, вы должны просто определить a long long объект.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top