Conversión de matriz de caracteres sin firmar a larga, larga [cerrada]
-
21-12-2019 - |
Pregunta
No estoy seguro de si esto es correcto, lo he probado y parece que algunos bytes están fuera de lugar...Básicamente tengo lo siguiente:
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
¿A alguien le importaría señalar dónde me equivoqué?Gracias.
Solución
estas configurando nNewValue
a la dirección de szBuffer
, en lugar de leer datos de esa dirección.Usar:
long long nNewValue = *reinterpret_cast<long long*>(szBuffer);
Otros consejos
Cambiar esta declaración
long long nNewValue = reinterpret_cast<long long>(szBuffer);
a
long long nNewValue = *reinterpret_cast<long long *>(szBuffer);
Aquí hay una versión modificada de su programa que funciona. en mi sistema (ampliado a un programa completo):
#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
Los dos primeros parámetros son de tipo void*
, por lo que no es necesario emitirlos;si los transmite (¿esa conversión está obsoleta en C++?), debe convertirlos a void*
, no char*
.
la asignación a nNewValue
convierte el DIRECCIÓN del buffer a long long*
, y luego elimina la referencia al valor convertido.
Pero esta es una mala idea.g++ me da una advertencia sobre la desreferencia del puntero convertido:
warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
Además, no hay garantía de que szBuffer
, que es una serie de unsigned char
, está correctamente alineado para que sus primeros bytes puedan tratarse de forma segura como un long long
objeto.El sistema x86 o x86_64 que probablemente esté utilizando tolera accesos a memoria desalineados, pero no todos los sistemas lo hacen.
Los lanzamientos de punteros a menudo no son seguros a menos que sepa exactamente que estas haciendo.
Si desea reinterpretar parte de una matriz de caracteres como un objeto de algún otro tipo, puede usar una unión si realmente necesita interpretar la memoria misma como un tipo diferente de objeto, o usar memcpy
.(Aun así, asegúrese de que realmente necesita hacer esto;es probable que no lo hagas.La mayoría de las veces, si desea almacenar un long long
objeto, deberías simplemente definir a long long
objeto.)