簡體   English   中英

使用帶有較小數組的越界索引是否安全,該數組是從足夠大的數組中生成的?

[英]Is it safe to use an out-of-bound index with an smaller array, which is casted from a large enough array?

在我的日常工作中,我遇到了很多類似以下模式的C代碼。 我擔心這種模式是否安全。

typedef struct
{
    unsigned char someField : 4;
    unsigned char someOtherField : 4;
    unsigned char body[1];
} __attribute__((__packed__, aligned(1))) SomeStruct;

int main()
{
    unsigned char pack[16] = {};
    SomeStruct* structPack = (SomeStruct*)pack;

    structPack->someField = 0xC;
    structPack->body[4] = 0x5;

    return 0;
}

讓我擔心的是程序使用的是structPack->body[4] ,它仍然是16字節數組的一部分,但是如果我們看一下SomeStruct的定義SomeStruct 所以有兩種方法來看待它:

  • 它指的是有效的內存位置。 沒有危險。
  • 它是越界的,因此是未定義的行為。

所以,我的問題是:

  1. 根據C標准(更具體地說,C89),這種模式是安全還是未定義的行為?
  2. 此外,對於某些特定的編譯器(尤其是GCC)或平台,它是否安全?
  3. 還有更好的選擇嗎?

請注意,此類代碼主要在微控制器上運行,有時在Linux桌面上作為應用程序運行。

通過不兼容的左值訪問對象是未定義的行為。 對齊可以通過屬性行解決,但使用指針訪問對象仍然違反嚴格別名:

unsigned char pack[16] = {};
SomeStruct* structPack = (SomeStruct*)pack;

6.5。 P7:

對象的存儲值只能由具有以下類型之一的左值表達式訪問:

- 與對象的有效類型兼容的類型,

- 與對象的有效類型兼容的類型的限定版本,

- 對應於對象的有效類型的有符號或無符號類型的類型,

- 對應於對象有效類型的限定版本的有符號或無符號類型,

- 聚合或聯合類型,其成員中包含上述類型之一(包括遞歸地,子聚合或包含聯合的成員),或者

- 角色類型。

有效類型是:

用於訪問其存儲值的對象的有效類型是對象的聲明類型(如果有)。

SomeStruct*與char數組不兼容。

分配SomeStruct的正確方法是使用內存分配器或alloca(如果需要考慮,將分配堆棧)如果支持該功能。

仍然存在body構件的問題,該構件是尺寸為一的陣列並且標准將不允許其越過界限(即身體[1])。 c99引入了一個靈活的陣列成員解決方案:

typedef struct
{
    unsigned char someField : 4;
    unsigned char someOtherField : 4;
    unsigned char body[];    //must be last
}...

當您設置大小以分配此結構時,您可以根據body[]成員需要的大小來添加其他大小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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