Неподписанные массивы символов приводятся к long long

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

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

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

1

Решение

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

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

Другие решения

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

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

в

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

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

#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 объект, вы должны просто определять long long объект.)

0
По вопросам рекламы [email protected]