[英]How does the computer(C compiler, or something else) handle “automatic array declaration”? | C language
我試圖從函數返回一個動態聲明的數組; 迄今我返回結構的指針保持到存儲器塊malloc()
分配給該數組和一個整數來存儲陣列的長度。
這讓我很奇怪; C編譯器 (或其他)如何處理程序中聲明的自動數組? 例如。
main()
{
//delcare an array holding 3 elements
int array[] = {1,2,3};
/*variable to hold length of array
*size of array / size of 1st element in the array == length of the array
*this will == 3
*/
int array_Length = (sizeof(array))/(sizeof(*array));
//call malloc for a block of memory to hold 3 integers(worth of memory)
int* ptr = malloc(3*(sizeof(int)));
/*not exactly sure what this formula means when using a pointer???
*but it seems to always == 1
*/
int dynamic_array_length = (sizeof(ptr))/(sizeof(*ptr));
return 0;
}
我的觀點是 , sizeof()
運算符以某種方式知道自動聲明的數組中有3個整數。
或者更一般地說 :
sizeof(array)
其中array
是(N x type_size)
N是array
中元素的數量
type_size是用於存儲數據類型的內存字節數
自動數組是否存儲有關其大小/長度的其他信息?
動態數組是否存儲不同? ( 我知道我們控制何時從內存中釋放動態變量 )
運算符sizeof
是一個編譯時構造(VLA參數除外)。 它以字節為單位告訴您對象大小,因為它知道確切的編譯時對象類型。 當你知道確切的類型,大小也立即知道。 無需在任何地方單獨存儲元素數量。
你的聲明
int array[] = {1,2,3};
相當於
int array[3] = {1,2,3};
意味着該array
具有int[3]
類型。 所以你的sizeof(array)
被解釋為sizeof(int[3])
,編譯器會立即知道它。
sizeof
不知道也不關心你的任何“動態陣列”。 它所關心的是sizeof(ptr)
操作符sizeof
應用於指針。 所以它評估指針大小。
sizeof(...)
不是函數調用。 它實際上並不在運行時執行 - 該值在編譯時被替換,因此實際編譯的是:
int array_length = 3;
dynamic_array_length
的計算不正確。 您將指針的大小除以int的大小。 在你的情況下碰巧是相同的,結果得到1
。
您的動態數組以不同方式存儲 - 指針(在堆棧上)與數據(在堆上)分開。 第一個數組只是堆棧上的數據 - 內存地址是常量(對於該堆棧幀)並在需要時使用。
忽略VLA,自動數組的數組大小在編譯時是完全已知的,並且實際上是變量類型的一部分。 sizeof
是對類型系統的查詢(在編譯時解析),類型系統在編譯時僅存在於編譯器內部數據結構中。 結果是實際的變量大小,它基本上被視為直接寫在源代碼中。
關於sizeof
事情已經討論得足夠多了,我們知道它是一個編譯時的動作。
但事實上,確實有一些關於大小的東西存儲並在運行時用於動態變量。 否則free
無法正常工作。
這是一個很好的參考: 如何做malloc和免費工作
您正在遇到C的一個不一致之處。數組只是一個指針,除非它已被聲明。 sizeof(somearray)的結果是不同的,這取決於sizeof是否在定義somearray的函數中使用。 在C中,一旦你離開定義,就不會知道除了數組中對象類型之外的任何東西。 這只是C編程容易出錯的眾多原因之一。
除C之外的大多數編程語言或從C派生的編程語言都維護一個數組描述符,其中包括維數,元素數,以及在某些情況下,數組邊界。
在動態數組的情況下,庫通常會在返回的內存中增加開銷(有時會在末尾添加額外的開銷)。 使用它以便庫可以知道釋放了多少內存。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.