前言 :我們知道內存分為 棧 堆 其實在計算機中是不存在差別的,只是程序員手動分類 方便處理
案例1 我們直接創建一個在棧區的40m大小數組案例2 在堆區創建一個40m的數組案例3 多次動態分配堆內存 不釋放案例4 手動釋放內存案例5 申請內存另一個api案例6 DEMOrealloc
C語言內存分配: 1. 棧區(stack) windows下,棧內存分配2M(確定的常數),超出了限制,提示stack overflow錯誤 自動分配,釋放 2. 堆區(heap) 程序員手動分配釋放,操作系統80%內存 3. 全局區或靜態區 4. 字符常量區 5. 程序代碼區

結果:棧溢出
malloc函數分配堆內存并返回對應指針 頭文件stdlib.h sizeof 返回對應變量所占字節數
結果:正常 
在執行睡眠的時候我們看看程序所占內存大小40mb 
睡眠結束后 程序內存變為80mb 
我們申請了兩次內存分別為40mb,發現再第二次申請的時候內存所占變為80 可見第一次申請的內存并沒有釋放
上面的代碼運行預期結果應該是:手動釋放了第一次申請的40mb 內存 ,然后有申請了一次40mb 所以程序運行結束休眠后應該還是40mb
結果:和預期一致 
內存重新分配,當你動態內存申請40mb的數組此時你不夠用怎么辦?便可以重新調用realoc來重新分配內存
void main(){ //第一個參數申請數量, 每個申請數量的大小 那么這里還是申請40mb int * a = calloc(1024 * 1024 * 10, sizeof(int)* 2); //重新申請80mb 第一次申請的內存區域如果和新申請的區域不再同一段 那么 賦值數據到新內存段,并釋放久指針內存區域 int * b=realloc(a, 1024 * 1024 * 10 * sizeof(int)* 2); getchar();}
注意新申請的內存 可能會在原來內存地址上基礎上擴展/縮小,也有可能在某個新的內存地址段 申請一塊 并且拷貝舊數據到新內存,同時釋放舊內存 百度百科 : realloc分配一個newsize的內存塊,返回一個指向該內存塊的指針。 如果newsize大小為0,那么釋放mem_address指向的內存,并返回NULL。 如果沒有足夠可用的內存用來完成重新分配(擴大原來的內存塊或者分配新的內存塊),則返回NULL。而原來的內存塊保持不變。 現存的數據然后就被拷貝至新的位置,而老塊則放回到堆上.重要的信息就是數據可能被移動
總結:
realloc失敗的時候,返回NULLrealloc失敗的時候,原來的內存不改變,不會釋放也不會移動假如原來的內存后面還有足夠多剩余內存的話,realloc的內存=原來的內存+剩余內存,realloc還是返回原來內存的地址; 假如原來的內存后面沒有足夠多剩余內存的話,realloc將申請新的內存,然后把原來的內存數據拷貝到新內存里,原來的內存將被free掉,realloc返回新內存的地址如果size為0,效果等同于free()。這里需要注意的是只對指針本身進行釋放,例如對二維指針**a,對a調用realloc時只會釋放一維,使用時謹防內存泄露。傳遞給realloc的指針必須是先前通過malloc(), calloc(), 或realloc()分配的 6.傳遞給realloc的指針可以為空,等同于malloc。新聞熱點
疑難解答