어떻게 float 값을 작성합니까?
다른 데이터 크기를 가진 여러 객체를 처리하는 프로젝트에서 이미 작업하고 있습니다. 우리는 체인 목록에 객체 속성을 유지하려고하지만 하나의 커다란 공통 버퍼에 데이터를 저장합니다. 따라서이 버퍼에는 8 비트 부호있는 정수와 32 비트 부동 소수점, 부호없는 정수 64 비트 등이 있습니다. 분명히 아무도 공간을 절약하기 위해 정렬 된 첫 번째 요소를 제외하고는 없습니다. 우리가 값을 기록 할 때 그래서 우리가 할 :
// Write float value to any position in your big buffer
float fValueToWrite = 10;
memcpy(ptr + 12, &fValueToWrite, sizeof(fValueToWrite));
우리는 우리가 할 값을 읽고 자하는 경우 : 트릭 비에서 읽기에 대해 걱정하지 않는다 방어 적이기을 사용
// Read the float from any unalign position of your big buffer
float fReadValue = 0;
memcpy(&fReadValue, ptr + 12, sizeof(fReadValue));
단어 경계.
그러나 우리는 읽을 이런 짓을하는 경우 :
float buffer[256] = {0};`
uint8_t* ptr = (uint8_t *)buffer;
float fCrashReadValue = *((float *)(ptr + 11));
이 (권자 실제로는 소수의) (11)에 의해 경계 나누어 읽는 지원하지 않는 프로세서에 정렬 오류가 발생할 수 있습니다. 따라서 CPU가이 경우 32 비트 인 경우 ptr
이 할당 된 버퍼를 가리키고 제대로 정렬되지 않은 다른 포인터를 가리키는 경우 12이 유효한 경계가됩니다.
내가 경험 한 많은 ARM 프로세서는 경계가 아닌 주소를 사용하여 오류가 발생할 것이라고 말할 수 있습니다. 그러나 x86 (Intel) 프로세서는 조용히 페널티 성능을 재편성합니다.
희망 사항 :
테스트 됨 - 배열이 제대로 초기화되면 충돌이 발생하지 않아야합니다. 이 짧은 코드는 충돌하지 않고 올바른 결과를 출력합니다 : 'float num; uint8_t arr [4]; uint8_t * ptr = & arr [0]; num = 14; * ((float *) (ptr)) = num; num = * ((float *) (ptr)); ' – xinaiz
[MCVE] (https://stackoverflow.com/help/mcve)를 제공해주십시오. – Xiobiq
'ptr'가'sizeof (float)'주소로 나눌 수있는 좋은 점을 가리키지 않는다면 정렬 문제가 발생할 수 있습니다. 그러나 [mcve]를 요구하는 군중에 가입합니다. – user4581301