簡體   English   中英

如何解決 C 中的指針轉換以避免未對齊的 memory 訪問?

[英]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-CClang 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM