[英]How to work around pointer casting in C to avoid unaligned memory access?
我最近了解到,指針轉換可能會觸發未對齊的 memory 訪問,例如在
void test_func(uint8_t *data) {
/*The rest of the code removed for clarity*/
uint32_t value = *((uint32_t *) data);
}
但是,如果我真的需要轉換指針,我該如何解決呢? 在上面的示例中,如果我必須以uint32_t
訪問data
但仍想避免未對齊的 memory 訪問,該怎么辦?
如何解決指針轉換...以避免未對齊的 memory 訪問?
使用memcpy(&value, data, sizeof value);
傳輸數據而不是*((uint32_t *) data)
。 一個好的編譯器會發出高效的代碼。
uint8_t data[4] = { 1,2,3,4};
uint32_t value;
memcpy(&value, data, sizeof value);
...或確保uint8_t value[]
與union
對齊,通過*alloc()
alignas
union {
uint8_t data[4];
uint32_t d32;
} x;
...
test_func(x.data) {
#include <stdalign.h>
alignas(uint32_t) uint8_t data[4] = { 1,2,3,4};
test_func(data);
uint8_t *data = malloc(sizeof *data * 4);
...
test_func(data);
free(data);
如何解決 C 中的指針轉換以避免未對齊的 memory 訪問?
您不能(例如,在 x86-64 上未對齊的 memory 訪問是可能的,但速度很慢;在Arduino -s 上也可能出現這種情況)。
另請參見 C11 的_Alignas
和_Alignof
運算符。
在許多實現中,可以從intptr_t
來回轉換指針,然后您可以玩按位技巧。
在上面的示例中,如果我必須以
uint32_t
訪問data
但仍想避免未對齊的 memory 訪問,該怎么辦?
您需要確保test_func
的調用者傳遞了一個對齊良好的指針。
Frama-C 、 Clang static 分析器之類的工具可以幫助您,或者也許在 spring 2021 結束時, Bismon
您可以#include <assert.h>
並添加,作為test_func
的第一條語句: assert((intptr_t)data % sizeof(uint32_t) == 0);
; 參見例如assert(3) 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.