VC 乙個函式引起的思考

2021-04-13 00:55:05 字數 1642 閱讀 8685

windows一些系統函式返回值是指標,例如

char far* inet_ntoa(

struct in_addrin

);

這個函式傳入乙個結構,返回乙個指向字串的指標,一般c++程式設計中介面設計的時候對記憶體的使用都是堅持誰申請誰釋放,這樣才不會造成忘記釋放的記憶體洩漏問題。

可是這個函式直接返回乙個指標,如果是一般的函式肯定是申請的堆疊空間,而堆疊申請的空間必須通過顯式釋放的方式釋放,例如free(void *p)、delete,否則就會造成記憶體洩漏。

那這個函式返回的指標什麼時候釋放呢?

於是在呼叫結束後試圖釋放它:

char *strip = inet_ntoa(add);//假設in_addr add;已存在並賦值

free(strip);

可是以上**執行到free(strip)就會出現如下錯誤:

如果使用delete strip也會出現同樣的錯誤。

問題是不釋放會不會造成記憶體洩漏?

一次偶然的機會,發現連續兩次呼叫inet_ntoa函式,最後得到兩次結果總是相同的,也就是兩次執行完後,無論兩次傳入的引數是否相同,最後兩次儲存的結果都是相同的!

再進一步跟蹤,發現其實第一次和第二次返回指標指向的字串值並不想同,只是執行到第二次的時候第乙個返回值也改變了!

char *strip1 = inet_ntoa(add1);//返回乙個ip位址字串

char *strip2 = inet_ntoa(add2);//返回另乙個ip位址字串,但是strip1也跟這個返回值一樣了。

原來inet_ntoa函式每次返回的是同乙個記憶體塊,而這個記憶體塊是系統記憶體,因此它並不釋放。

不釋放可以,但問題又來了,如果我多個執行緒同時呼叫inet_ntoa能保證每次呼叫返回的都是自己要的正確結果嗎?

如果在這個函式返回之前切換到另乙個執行緒,同樣呼叫了這個函式,第二次呼叫覆蓋了第一次結果,這時一次的結果就是錯誤,在網路程式設計中,這是很要命,明明是發給這個ip的資料,發到另外乙個ip去了,甚至導致系統崩潰。

這個問題還是可以通過加鎖的方式來保證資料的正確性的,如下:

thread1

mutex1.lock();

char *str1 = (char*)malloc(20);

strcpy(str1,inet_ntoa(add1));//add1假設已經存在並賦值

mutex2.unlock();

//othercode

thread2

mutex2.lock();

char *str2 = (char*)malloc(20);

strcpy(str2,inet_ntoa(add2));//add2假設已經存在並賦值

mutex2.unlock();

//other code

這樣在每次使用inet_ntoa函式之前加鎖,在正確返回並儲存返回值後解鎖,就不會出現上面所說的衝突,但誓畢影響程式的效率。

看來在使用有些windows系統函式之前還是要小心,沒有充分了解這些介面的特徵就會造成意想不到的錯誤。 

strcpy函式引起的思考

不呼叫庫函式,實現strcpy函式。解釋為什麼要返回char 解說 strcpy的實現 char strcpy char strdest,const char strsrc if null strdest null strsrc 1 throw invalid argument s 2 char s...

memcpy引起的乙個bug

void memcpy void dest,const void src,size t n 由src指向位址為起始位址的連續n個位元組的資料複製到以dest指向位址為起始位址的空間內。memcpy dest,0,5 真正應該使用的是 memset dest,0,5 關於memset memset 函...

乙個引數引起的血案

問題產生實際情況 資料庫被強制乾掉,空間漲到100 分析 經觀察發現是由於pg log目錄增長過快導致磁碟空間被爆。pg log是如何產生的?記錄資料庫執行日誌,內容可讀,預設關閉,需要設定引數啟動。1.error資訊。2.定位慢查詢sql。3.資料庫的啟動關閉資訊。4.pg系統相關警告資訊等。根據...