c 中能否判斷乙個指標指向棧還是堆?

時間 2021-06-03 15:24:52

1樓:Rico

如果假定指標非堆即棧,不考慮 code 、bss 、mmap 這些段位址的話,應該是可以的。

提供乙個思路:

1 讀取暫存器狀態

2 通過 $rbp $ebp 回溯堆疊,找到頂級堆疊的 $ebp,也就是整個程序(執行緒)的堆疊起始位址

3 使用指標位址與堆疊起始位址比較,差值與平台相關的最大堆疊size 比較

2樓:

bool test(void *p)

隨手寫的,未經測試。

條件:1 編譯優化得全關了。

2 不能有多執行緒,訊號,中斷等等等等

3 不能處理從外部(如system trap)傳入指標

4 被test的必須是乙個合法的(非懸空)、指向資料的指標

假設架構上0x0是棧底,堆從記憶體位址的另一端分配。

考慮乙個合法的指標q被傳入test,像這樣:

void *q = getAPointer(......);

bool isStackPointer = test(q);

若q指向棧:

呼叫test前,test函式的呼叫棧還未被構建,但q指標已經指向某個函式的呼叫棧記憶體。

呼叫test後,test函式的呼叫棧被構建,處於程式棧記憶體的最下端。

即test的呼叫棧裡任意一塊記憶體的位址比任何其他合法的棧記憶體位址(包括q所在的記憶體位置) 都要大。

p是乙個在test呼叫棧上的變數,所以&p是乙個指向test呼叫棧的指標,而p的值等於q,所以p < &p成立,返回true

若q指向堆:

按照假設,堆從記憶體的另一端(高位址)開始分配,那麼堆位址大於任何棧位址。前面已經說明&p是乙個指向棧的指標。而所以p的值即q所指的堆記憶體位址大於&p的值即test呼叫棧上的記憶體位址,返回false。

3樓:MaskRay

Linux的話,可以檢視程序 $PID 的位址空間對映

@烏鴉提到heap不一定都在brk下面。

glibc的void *malloc(size_t size)實現,在size較大時會使用mmap分配,否則在一塊預先申請的arena裡分配。多執行緒環境下可能有多個arena,其中第乙個是[heap],應該是用brk()得到的,其他是mmap的,不檢視malloc實現相關的資料結構很難和其他mmap的空間區分。

@RednaxelaFX 提到多執行緒下新建執行緒的棧都是[anon]。

/proc/$pid/maps 和 /proc/$pid/task/$tid/maps 有所區別。我在Arch Linux core/linux 3.19.

3-3下發現 /proc/$pid/maps 會標出其他執行緒的棧:[stack:$tid],而 pmap -x 會把 [stack:

$tid] 顯示為 [anon],pmap -X 保留 maps 裡的字樣。

單執行緒環境下似乎heap物件指標值均小於program break,而棧物件指標值均大於:

#include

#include

#include

int main()

另外乙個可能不是隨時都管用的方法,https://gcc.gnu.

org/onlinedocs/gcc/Local-Reg-Vars.html#Local-Reg-Vars 獲取暫存器RSP的值 不過ESP/RSP不一定都小於所有區域性變數的位址。

#include

#include

int main()

其他 malloc 實現不知道是什麼樣。

4樓:

需要注意的是指標指向的記憶體並不是非堆即棧的,比如函式指標,以及程式呼叫系統介面自己申請的虛擬記憶體等。C++語言本身沒法做棧或堆的判斷,針對特定平台的hack方法是有的。

一般執行緒的棧大小是固定值的,如果建立時不指定棧大小,此執行緒的棧指標之間的距離不會高於這個值,可以作為判斷條件之一。

堆一般都會維護已分配記憶體的列表,可以遍歷比較。但不同系統的堆實現差別很大,也沒有通用的方法。

C 指標「指向緊鄰物件所佔空間的下乙個位置」是什麼意思?

張擘 作者寫這幾種情況表示的是指標在生命週期內,所有可能的狀態,它的值會是哪些,就這麼簡單。eg int int 那麼這個指標 解引用 就是 就是指向緊鄰物件所佔空間的下乙個位置,但是他解引用會是什麼呢,不確定的。 李小明 尾後迭代器那種.就比如int ia 100 取乙個陣列的最後元素的後乙個指標...

在指向行的指標前面加乙個 就轉換為指向列的指標,為什麼啊?

心裡藏著小怪獸 其實不需要理會行和列的說法,反正說到行和列我也懵逼,以下以三維陣列為例以我的角度來理解下這個問題,可能有點答不對題。陣列宣告如下 假定是int的儲存大小為4個位元組 int arr 10 8 3 1.首先無論是幾維陣列,其都代表一段連續的記憶體,只不過為了能夠描述一些問題強制分了維度...

C 中宣告 const 乙個指標到底宣告的是什麼?

二圈妹 要知道指向常量的指標 pointer to const 和常量指標 const pointer 的區別 僅僅要求這個指標指向常量,我們可以修改指標的指向,甚至可以讓它指向相應的非常量資料型別 常量指標是指向的位置不變,它不一定需要指向常量。更詳細的 二圈妹 const 搭配指標和引用 C P...