簡體   English   中英

C 語言中 memory 分配的本地和全局數組有什么區別?

[英]What is difference for local and global array for memory allocation in C language?

我編寫了一個程序來檢查全局數組和本地數組的數組越界。

情況1:

/* Local and global Aoob demo*/

uint8  problematic_array_global[5] = {22,34,65,44,3};
uint16 adjacent_array_global[3] = {82,83,84};

void aoob_example()
{
/*Global*/
    printf("            Before global Aoob , adjacent_array={%u,%u,%u}\n",adjacent_array_global[0],adjacent_array_global[1],adjacent_array_global[2]);
    
    uint8 idx = 0;
    
    for(;idx < 15;idx++)
    {
        problematic_array_global[idx] = idx;
    
    }
    printf("            After global Aoob  , adjacent_array={%u,%u,%u}\n",adjacent_array_global[0],adjacent_array_global[1],adjacent_array_global[2]);

並得到了結果:

Before global Aoob , adjacent_array_global={82,83,84}
After global Aoob  , adjacent_array_global={2312,2826,3340}

案例二:

void aoob_example()
{
    uint8 problematic_array[5] = {1,2,3,4,5};
    uint8 adjacent_array[3] = {12,13,14};
    
    printf("            Before Aoob var=%u , adjacent_array={%u,%u,%u}\n",var,adjacent_array[0],adjacent_array[1],adjacent_array[2]);
    uint8 idx = 0;
    
    for(;idx < 8; idx++)
    {
        problematic_array[idx] = idx;
    
    }
    printf("            After Aoob var =%u , adjacent_array={%u,%u,%u}\n",var,adjacent_array[0],adjacent_array[1],adjacent_array[2]);

並得到了結果:

Before Aoob var=10 , adjacent_array = {12,13,14}
After Aoob var =10 , adjacent_array = {12,13,14}

盡管我已經在附近聲明了 2 個本地 arrays 並且 for 循環最多 8 次迭代,但似乎使用本地數組我們沒有任何超出范圍的數組。

2聲明有什么區別? 這個程序中memory中的數組是如何存儲的? 這里發生了什么? 如何理解 c 中的這種行為?

在附近的兩個 arrays 中,只有一個會在超出范圍時覆蓋另一個。 該鄰接的順序未定義。

這是一個因素。 另一個是編譯器優化和警告。 使用全局-O1和 -O1 我得到:

 mov    BYTE PTR [rip+0x2ec6],0x0        # 4030 <problematic_array>
 mov    BYTE PTR [rip+0x2ec0],0x1        # 4031 <problematic_array+0x1>
 mov    BYTE PTR [rip+0x2eba],0x2        # 4032 <problematic_array+0x2>
 mov    BYTE PTR [rip+0x2eb4],0x3        # 4033 <problematic_array+0x3>
 mov    BYTE PTR [rip+0x2eae],0x4        # 4034 <problematic_array+0x4>
 mov    BYTE PTR [rip+0x2ea8],0x5        # 4035 <adjacent_array>
 mov    BYTE PTR [rip+0x2ea2],0x6        # 4036 <adjacent_array+0x1>
 mov    BYTE PTR [rip+0x2e9c],0x7        # 4037 <adjacent_array+0x2>

所以編譯器確切地知道發生了什么,並且有一個警告:

warning: iteration 5 invokes undefined behavior

problematic_array不寫入adjacent ,它會寫入任何其他內容,無論后果如何。

使用本地 arrays 會涉及堆棧區域(檢測到堆棧粉碎),但基本問題是相同的。 任何東西都可能被覆蓋。

在這里,編譯器有機會發出警告,因為是常數。 通常,ooB 更微妙,並且編譯器不易預測。

帶本地 arrays

訪問索引為5problematic_array是無效的。 數組被“越界”訪問。 該數組的大小為5 ,因此您可以訪問索引04的元素。

如何理解 c 中的這種行為?

這種 class 的行為稱為“未定義行為”。 您的代碼的行為沒有定義,沒有人知道應該發生什么,任何事情都可能發生,什么都不會發生。 術語“未定義的行為”應該很容易用谷歌搜索,甚至在 wiki 上 - 您可以從未定義、未指定和實現定義的行為中了解更多信息。


C 語言中 memory 分配的本地和全局數組有什么區別?

不同之處在於變量 scope(全局 arrays 可以從任何地方訪問)和生命周期(全局數組在程序期間處於活動狀態,而本地 arrays 一直活動到塊結束)。 請參閱https://en.cppreference.com/w/c/language/scopehttps://en.cppreference.com/w/c/language/lifetime

好吧,在這種特定情況下,它會以某種方式影響編譯器生成的代碼。 找出答案的唯一方法是檢查生成的機器代碼。

2聲明有什么區別?

在第一種情況下,變量在文件 scope 中定義,其中一個是uint16

在第二個中,兩者都是uint8並在塊 scope 中定義。

不要使用uint8 uint16 - 使用標准化stdint.h中的標准化uint8_tuint16_t https://en.cppreference.com/w/c/types/integer

這個程序中memory中的數組是如何存儲的?

保證連續的數組元素被分配在連續相鄰的 memory 位置。

這兩個 arrays 之間沒有關系。 它們彼此無關,除了它們在源代碼中的定義很接近。

這里發生了什么?

您的代碼無效,編譯器正在生成代碼。 在第一種情況下,編譯器“發生”了覆蓋另一個數組的指令,而在第二種情況下,它沒有發生。 您只能逐行檢查編譯器生成的機器代碼和 go 以找出真正發生的情況。

暫無
暫無

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

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