Transmissão de array de caracteres não assinados para longo longo [fechado]
-
21-12-2019 - |
Pergunta
Não tenho certeza se isso está correto, testei e parece que alguns bytes estão errados...Basicamente, tenho o seguinte:
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
Alguém se importaria de apontar onde errei?Obrigado.
Solução
Você está configurando nNewValue
para o endereço de szBuffer
, em vez de ler dados desse endereço.Usar:
long long nNewValue = *reinterpret_cast<long long*>(szBuffer);
Outras dicas
Alterar esta declaração
long long nNewValue = reinterpret_cast<long long>(szBuffer);
para
long long nNewValue = *reinterpret_cast<long long *>(szBuffer);
Aqui está uma versão modificada do seu programa que funciona no meu sistema (expandido para um 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
Os dois primeiros parâmetros de são do tipo void*
, então você não precisa lançá-los;se você convertê-los (essa conversão está obsoleta em C++?), você deve convertê-los para void*
, não char*
.
A atribuição a nNewValue
converte o endereço do buffer para long long*
, e, em seguida, desreferencia o valor convertido.
Mas isso é uma má ideia.g++ me dá um aviso sobre a desreferência do ponteiro convertido:
warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
Além disso, não há garantia de que szBuffer
, que é uma matriz de unsigned char
, está alinhado corretamente para que seus primeiros bytes possam ser tratados com segurança como um long long
objeto.O sistema x86 ou x86_64 que você provavelmente está usando tolera acessos desalinhados à memória, mas nem todos os sistemas fazem isso.
Os lançamentos de ponteiro geralmente são inseguros, a menos que você saiba exatamente o que você está fazendo.
Se você quiser reinterpretar parte de uma matriz de caracteres como um objeto de algum outro tipo, você pode usar uma união se realmente precisar interpretar a própria memória como um tipo diferente de objeto, ou usar memcpy
.(Mesmo assim, tenha certeza de que você realmente precisa fazer isso;é provável que você não saiba.Na maioria das vezes, se você quiser armazenar um long long
objeto, você deveria apenas definir a long long
objeto.)