![](/img/trans.png)
[英]difference in array declaration and array memory allocation for local variables and fields in C#
[英]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
訪問索引為5
的problematic_array
是無效的。 數組被“越界”訪問。 該數組的大小為5
,因此您可以訪問索引0
到4
的元素。
如何理解 c 中的這種行為?
這種 class 的行為稱為“未定義行為”。 您的代碼的行為沒有定義,沒有人知道應該發生什么,任何事情都可能發生,什么都不會發生。 術語“未定義的行為”應該很容易用谷歌搜索,甚至在 wiki 上 - 您可以從未定義、未指定和實現定義的行為中了解更多信息。
C 語言中 memory 分配的本地和全局數組有什么區別?
不同之處在於變量 scope(全局 arrays 可以從任何地方訪問)和生命周期(全局數組在程序期間處於活動狀態,而本地 arrays 一直活動到塊結束)。 請參閱https://en.cppreference.com/w/c/language/scope和https://en.cppreference.com/w/c/language/lifetime 。
好吧,在這種特定情況下,它會以某種方式影響編譯器生成的代碼。 找出答案的唯一方法是檢查生成的機器代碼。
2聲明有什么區別?
在第一種情況下,變量在文件 scope 中定義,其中一個是uint16
。
在第二個中,兩者都是uint8
並在塊 scope 中定義。
不要使用uint8
uint16
- 使用標准化stdint.h
中的標准化uint8_t
和uint16_t
。 https://en.cppreference.com/w/c/types/integer
這個程序中memory中的數組是如何存儲的?
保證連續的數組元素被分配在連續相鄰的 memory 位置。
這兩個 arrays 之間沒有關系。 它們彼此無關,除了它們在源代碼中的定義很接近。
這里發生了什么?
您的代碼無效,編譯器正在生成代碼。 在第一種情況下,編譯器“發生”了覆蓋另一個數組的指令,而在第二種情況下,它沒有發生。 您只能逐行檢查編譯器生成的機器代碼和 go 以找出真正發生的情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.