i. crt
crt(c/c++ runtime library)是支援c/c++執行的一系列函式和**的總稱。雖然沒有乙個很精確的定義,但是可以知道,你的main就是它負責呼叫的,你平時呼叫的諸如strlen、strtok、time、atoi之類的函式也是它提供的。我們以microsoft visual.net 2003中所附帶的crt為例。假設你的.net 2003安裝在c:program filesmicrosoft visual studio .net 2003中,那麼crt的源**就在c:program filesmicrosoft visual studio .net 2003vc7crtsrc中。既然有了這些實現的源**,我們就可以找到一切解釋了。
ii. _beginthread/_endthread
iii. createthread和crt
或許有人會說,我用createthread建立執行緒以後,我也呼叫了c執行庫函式,並且也使用exitthread退出了,可是我的程式執行得好好的,既沒有因為crt沒有初始化而崩潰,也沒有因為忘記呼叫_endthread而發生記憶體洩漏,這是為什麼呢,讓我們繼續我們的crt之旅。
假設我用createthread建立了乙個執行緒,我呼叫strtok函式來進行字串處理,這個函式肯定是需要某些額外的執行時支援的。strtok的源**在strtok.c中。從**可見,在多執行緒情況下,strtok的第一句有效**就是_ptiddata ptd = _getptd(),它通過這個來獲得當前的ptd。可是我們並沒有通過_beginthread來建立ptd,那麼一定是_getptd搗鬼了。開啟tidtable.c,可以看到_getptd的實現,果然,它先嘗試獲得當前的ptd,如果不能,就重新建立乙個,因此,後續的crt呼叫就安全了。可是這塊ptd最終又是誰釋放的呢?開啟dllcrt0.c,可以看到乙個dllmain函式。在vc中,crt既可以作為乙個動態鏈結庫和主程式鏈結,也可以作為乙個靜態庫和主程式鏈結,這個在project setting->code generations裡面可以選。當crt作為dll鏈結到主程式時,dllmain就是crt dll的入口。windows的dllmain可以由四種原因呼叫:process attach/process detach/thread attach/thread detach,最後乙個,也就是當執行緒函式退出後但是執行緒還沒有銷毀前,會在這個執行緒的上下文中用thread detach呼叫dllmain,這裡,crt做了乙個_freeptd(null),也就是說,如果有ptd,就free掉。所以說,恰巧沒有發生記憶體洩漏是因為你用的是動態鏈結的crt。
於是我們得出了乙個更精確的結論,如果我沒有使用那些會使用_getptd的crt函式,使用createthread就是安全的。
iv. 使用ptd的函式
那麼,究竟那些函式使用了_getptd呢?很多!在crt目錄下搜尋_getptd,你會發覺很多意想不到的函式都用到了它,除了strtok、rand這類需要保持狀態的,還有所有的字串相關函式,因為它們要用到ptd中的locale資訊;所有的mbcs函式,因為它們要用到ptd中的mbcs資訊,...。
理解C C 執行時庫
執行時庫 runtime library 通俗的說就是我們的程式執行的時候所依賴的庫檔案,在windows平台這些庫由微軟提供,並且是以2種形式提供 靜態庫 lib 動態庫 lib dll 每個庫還都提供debug release2個版本。c c 執行時庫從形式上來講和我們自己開發的靜態庫 動態庫沒...
C C 執行時庫堆記憶體分析
3.crtheap堆 4.靜態crt庫帶來的影響 5.總結 在c c 語言中,我們知道記憶體分為這幾種 程式全域性變數記憶體。棧記憶體。堆記憶體。其中堆記憶體就是通過malloc new 來分配的記憶體,本文我們來 一下堆記憶體的分配過程。對記憶體的使用非常簡單,如下就可以正常使用 int p in...
C C 執行時的種類
一 c c 執行時的種類 vc 完美的支援c和c 標準,因此也就按照c和c 標準定義的函式原型實現了上述執行時庫。為了方便有不同需求的客戶使用,vc 分別實現了動態鏈結庫dll版本和靜態鏈結庫lib版本。同時為了支援程式除錯且不影響程式的效能,又分別提供了對應的除錯版本。除錯版本的名稱在releas...