各位大神 如果我一个结构体 的某个属性存了1000个数据 然后现在不想用了 我直接 把这个结构体的这个属性 == NULL 是不是就表示 这个结构体 又成了一个全新的结构体了 但是 我并没有free 那么是不是 堆内存里面 始终有一块区域没有被回收呢?
天蓬老师2017-04-17 12:06:40
變數所佔記憶體的回收方式取決於該變數的儲存類型(storage class),對於你講的結構體而言:
new
或malloc
得到的空間,它儲存在HEAP(堆)中,除非手動delete
或free
,否則空間會一直佔用直至進程結束。 更多關於儲存類型的信息,可以參考這篇部落格: http://harttle.github.io/2015/07/22/memory-segment.html
黄舟2017-04-17 12:06:40
闷声发大财,这是坠吼滴!
,但lz你這樣就是記憶體外洩啦。
C語言中記憶體分配會在三個地方:
堆
堆疊
暫存器
所謂的栈
、入栈
、出栈
、栈溢出
就是指這個,在函數中分配,在函數中釋放,棧的空間比較小,變異的時候就分配啦。詳情你可以去看看函數是如何呼叫的。你int a = 1024的時候就是在這分配的。
所謂的堆
,我們先來聊聊虛擬記憶體。你一定聽過這句戶:32位的系统最大寻址是4g
,這個尋址對應的就是你在堆上分配的內存,懂伐? 32位元下每個進程最多分配4g,記憶體是咋分配的不用你管,只要要找系統要就可以了,你malloc的時候就是在這裡分配的。
所謂的寄存器变量
,就是volatile
register
這個關鍵字修飾的變量,我也沒用過,似乎是告訴暫存器這個變數盡量給用暫存器儲存。可能做遊戲的時候會遇到吧。
現在你明白為什麼會記憶體洩漏了麼?系統給你4g記憶體分配的能力,不是說讓你一定要用滿這4g,而是你有分配的能力,用完記得還給系統,所以malloc需要free,new需要delete(C++)
(年代久遠,可能有誤,參考就好)
大家讲道理2017-04-17 12:06:40
關鍵還是看你的資料空間是怎麼分配的,
如果是編譯器分配的,那就無所謂,離開作用域就自動回收了。
如果你是用 malloc
之類的函數手工程式碼分配的,那就必須在適當的位置 free
怪我咯2017-04-17 12:06:40
想修正一個問題,結構的屬性能賦NULL嗎?難道不是對結構指標賦NULL?
簡單舉個例子 int i=NULL;//printf("%d",i);會顯示啥呢?
Deallocates the space previously allocated by malloc(), calloc() or realloc(). If ptr is null-pointer, the function does nothing.
看到了嗎?如果你是動態分配的記憶體空間,那麼你需要呼叫free來做記憶體空間的釋放了。
反之,你是靜態獲得的記憶體空間,結構體的指標賦NULL,你只是讓它指向的物理位址指到了空,結構的作用域不結束,記憶體空間就會被自動釋放嗎?這顯然不符合變數的生命週期。
ringa_lee2017-04-17 12:06:40
當然不可以,在你說的情境中,直接將指標置為NULL,那麼那塊記憶體還是被結構體實體佔用的,但是因為你將指標置為NULL,就沒有指標指向這塊被使用的內存,就丟失了這塊內存的地址,就會造成內存的洩露,直到你的程式退出時候才會釋放這塊內存。
但是如果你的程式是一直運行的,例如像很多伺服器是需要7*24運行的,那麼丟失的記憶體將一直無法釋放,可能導致你的記憶體慢慢的洩露,最後只能重啟系統
怪我咯2017-04-17 12:06:40
依照你說的結構體的屬性可以賦值為NULL,假定這個屬性是指針,又說這個屬性沒有free,假定這個屬性的值是malloc回傳的指標值。在這種情況下,將這個屬性賦值為NULL,malloc分配的記憶體空間還在堆中,如果這個屬性是這塊記憶體空間的最後一個指針,將該指針設為NULL後,沒人引用這塊內存空間,那麼這個記憶體空間就發生洩漏了,再也回收不了,直到進程退出。