[音樂播放] 道格·勞埃德:可以這麼建議 之前,從這裡開始。 如果你還沒有看過上的視頻 指針,你可能想這樣做第一。 因為這段視頻是另一種 與指針的工作方式。 因此,它會說話 一些概念 我們覆蓋的 指針視頻和我們 現在要粉飾他們, 假設他們已經 樣的了解。 所以,這只是你公平的警告 如果你看到這個視頻 你沒見過 指針視頻,它可能排序 在你的頭上飛一點點。 因此,這可能會更好 看它的順序。 因此,我們已經見過 方式與指針的工作, 這是我們申報 變量,然後我們 聲明另一個變量,指針 變量,指向它。 因此,我們已經創建了一個 使用一個名稱的變量,我們 有一個名字創建了第二個變量, 我們點了第二個變量 在第一次。 這種具有 問題雖然,因為它 要求我們確切地知道 多少內存我們 將需要的時刻 我們的編譯程序。 這是為什麼呢? 因為我們需要能夠以命名或 找出所有可能的變量 我們可能會遇到的問題。 我們可能有可能是一個數組 能夠容納大量的信息, 但它仍然不是 完全足夠精確。 如果我們不知道叫什麼, 如果我們不知道 多少錢,我們需要在編譯的時候? 或者,如果我們的節目會 跑了很長一段時間, 接受各種用戶 數據,我們不能真正 估計無論我們是 將需要1000台? 它不喜歡,我們可以 說,在命令行 輸入多少個項目 你認為你所需要的。 好吧,如果這猜測是錯誤的? 動態內存分配 排序可以讓我們的方式 要解決這方面的問題。 而它的方式做它 是通過使用指針。 我們可以用指針 可以訪問動態 分配的內存,內存, 分配為您的程序正在運行。 這不是分配在編譯時。 當你動態分配 內存它來自游泳池 內存被稱為堆。 以前,所有的我們已經記憶 一直與在使用過程中 一直在下從池中 的存儲器稱為棧。 一個好方法一般 保持mind--這條規則 並不總是保持為真, 但幾乎​​差不多 一貫主張true--是任何 時間你給一個變量命名 大概住在堆棧上。 而任何時候你不這樣做 給一個變量的名稱, 您可以使用動態內存? 分配,它生活在堆上。 那種現在我介紹這是 如果有內存這兩個池。 但是你可能已經看到了這 圖,這是一般 的表示 看起來是什麼樣的內存, 而我們不會關心所有 的東西在頂部和底部。 我們關心的是這部分 在此中間,堆和棧。 正如你可以看到 在看這個圖, 這其實不是兩個 內存單獨的池。 這是一個內存共享池 你從哪裡開始,在這個視覺 你在底部開始 並開始填補 從與棧的底部,和你 從頂部開始,並開始填充 從上而下的堆。 但它確實是 同一池中,它只是 不同點,不同的地點 在存儲器中被分配。 你可以用盡 內存是含 堆一路走 的底部,或具有 棧一路頂端, 或具有堆和棧 見面互相反對。 所有這些可以是條件 導致你的程序 運行內存不足。 所以記住這一點。 當我們談論 堆和棧 我們真的是在談論 內存相同的通用塊,只 該存儲器的不同部分。 那麼,我們如何動態地得到 首先分配的內存? 如何我們的計劃獲得 內存作為它的運行? C井提供了一個調用的函數 malloc的,內存分配器,這 您撥打一個電話來了,你傳遞 有多少你想要的內存字節。 所以,如果你的程序正在運行 你想要一個整數的運行時, 你可能會馬洛克四個字節 內存,malloc的括號四人。 馬洛克將通過 翻翻堆, 因為我們是動態 分配內存, 它會回報給你 一個指針,指向存儲器。 它不會給你的memory-- 它不給它一個名字, 它給你一個指針。 所以這就是為什麼我再次說 這是很重要的,也許 看完球視頻 之前,我們得過了頭到這一點。 所以malloc的是怎麼回事,以 還給你一個指針。 如果馬洛克不能給你任何 內存,因為你已經用完了, 它會給你回一個空指針。 你還記得,如果我們發生了什麼 嘗試取消引用一個空指針? 我們遭受賽格故障,對不對? 這可能不是很好。 所以每次撥打電話 永遠的malloc你,總是 需要檢查是否 指針它給你回空。 如果是,你需要結束程序 因為如果你嘗試取消引用 你要去的空指針 挨段錯誤 和你的程序是 不管怎樣都是崩潰。 那麼我們如何做靜態 得到的整數。 INT的X. 我們可能已經這樣做了 一群倍,對不對? 這將創建一個名為變量 X中住在堆棧中。 我們如何動態地獲得一個整數? 詮釋星PX等於malloc的4。 或者更準確 我們會說INT星級PX 等於為int的malloc的大小, 只是拋出一些較少 圍繞我們的計劃幻數。 這將獲得對我們 從堆四個字節的存儲器, 和指針我們得到 回到它被稱為像素。 然後,就像我們已經 以前做的我們 可以提領像素到 訪問內存。 我們如何從用戶那裡得到的整數? 我們可以說INT x等於拿到INT。 這是非常簡單的。 如果我們想創建一個數組什麼 第X住在堆棧上的花車? 浮stack_array--這就是名字 我們array--方括號中的X. 這為我們創建一個數組 第X住在堆棧上浮動。 我們可以創建float數組 家住堆了。 語法看起來可能 多一點麻煩, 但我們可以說浮法 明星heap_array等於 malloc的x次浮子的尺寸。 我需要足夠的空間來容納 x浮點點值。 所以說,我需要100 花車,或1000彩車。 因此,在這種情況下,這將是 400字節100輛彩車, 或4000個字節為1000輛彩車, 因為每個浮點佔用 4個字節的空間。 這樣做後,我可以使用 在heap_array方括號語法。 正如我會在stack_array,我 可以單獨訪問它的元素 使用heap_array零,heap_array之一。 回想起我們可以做到這一點的原因 是因為在C數組的名字 確實是一個指針 該數組的第一個元素。 所以,我們正在宣告一個事實 彩車的堆棧這裡陣列 其實是有點誤導。 我們真的是在 代碼第二行有 還創建一個指向一大塊 內存我們那麼做了一些工作。 這裡的大問題 雖然動態分配內存, 這就是為什麼它是真的 重要的是要養成一些好習慣 當你使用它。 不同於靜態聲明 記憶,你的記憶 不會自動返回到 當你的函數完成系統。 因此,如果我們有主,和 主調用一個函數 女,當f完成不管它做 並返回程序的控制 回存儲器的主,所有 使用F是給出回复。 它可以再次使用 通過一些其它方案, 或一些其它功能 被調用後來在主。 它可以再次使用同樣的內存了。 如果動態 雖然分配內存 你必須明確地告訴 系統,你就大功告成了。 它會抓住它適合你,這可能 導致一個問題,你跑出來 的存儲器。 而事實上,我們有時 這是一個內存洩漏。 有時這些內存洩漏 其實是可以真正毀滅性的 為系統的性能。 如果你是一個經常上網的用戶 您可以使用特定的Web瀏覽器, 我不會指名道姓這裡,但 有一些網頁瀏覽器在那裡 這是臭名昭著的實際上有 內存洩漏沒有得到修復。 如果你離開你的瀏覽器中打開 在很長的一段時間裡,天 和天或數週,你有時 可能會注意到,您的系統 是運行非常,非常緩慢。 和其中的原因是, 瀏覽器已經分配的內存, 但當時沒有告訴系統 它的完成它。 所以留下更少的內存 適用於所有的其他程序 有分享,因為你 leaking--的Web瀏覽器 程序正在洩漏內存。 我們如何給記憶回來 當我們用它做? 那麼幸運的是這是一個 很簡單的方法來做到這一點。 我們只是釋放它。 有一個所謂的自由功能, 它接受一個指向存儲器, 我們是好去。 所以我們可以說我們是在 我們的節目中間, 我們想對malloc 50個字符。 我們想的malloc數組,可以 可容納50個字符。 而當我們得到的指針回 即,該指針的名字是詞。 我們做任何我們 打算做的話, 然後,當我們 我們做的只是釋放它。 而現在我們又回到那些50 字節的內存回系統。 其他一些功能可以使用它們。 我們不必擔心遭受 內存洩漏,因為我們已經釋放了字。 我們已經給記憶回來了, 所以我們做的工作吧。 所以有三個 黃金法則,應該 牢記每當你 動態分配內存 使用malloc。 每個內存塊 你的malloc必須釋放 你的程序之前完成運行。 現在再次,在家電,或在 這種IDE發生反正你 你 - 當這無論如何都會發生 當你的程序被終止, 所有的內存將被釋放。 但它總體上是好的編碼 實踐總是,當你完成, 釋放你所mallocd。 這就是說,只有東西 你已經mallocd應該被釋放。 如果靜態聲明 整數,INT×半結腸, 家住在棧中,你 不那麼想免費的X。 因此,只有你所事 mallocd應該被釋放。 最後,不要隨意的東西的兩倍。 可導致 另一種奇怪的局面。 所以,你已經一切 mallocd必須被釋放。 只有你已經事 的malloc應該被釋放。 而且不要隨意一些的兩倍。 所以,讓我們通過一個例子在這裡 什麼樣的一些動態分配 內存可能看起來像混合 在一些靜態存儲器。 什麼可能發生在這裡? 看看你是否可以按照 同時,你猜是什麼 會發生什麼,我們去 通過對代碼的所有這些行。 所以我們說INT微米。 這裡會發生什麼? 嗯,這是非常簡單的。 我創建一個名為米的整型變量。 我顏色是綠色, 因為這是顏色 我用我說話的時候 關於整型變量。 這是一個盒子。 這就是所謂的米,你可以 它裡面存儲的整數。 如果我那麼說了什麼INT明星? 那麼這是非常相似的。 我創建一個盒子叫。 這是能夠保持為int 明星,指針為整數。 所以我著色它的綠色十歲上下也是如此。 我知道它有什麼 做的整數, 但它本身並不是一個整數。 但是,這幾乎是同樣的想法。 我創建了一個箱子。 這兩個權 現在住在堆棧上。 我已經給了他們倆的名字。 INT星級住宿等於為int的malloc的大小。 這其中可能有點棘手。 花一秒鐘想想你 希望發生這個圖上。 INT星級住宿等於為int的malloc的大小。 嗯,這並不僅僅創建一個框。 這實際上造成了兩箱。 它的聯繫,這也確立 在的關係的點。 我們分配了一個塊 內存堆。 請注意右上角方框 那裡沒有一個名稱。 我們mallocd它。 它存在於堆。 但B有一個名字。 這就是所謂的B A指針變量。 那住在堆棧上。 所以這是一塊內存 指向另一個。 B包含地址 該內存塊。 它不具有一個名字,否則。 但它指向它。 所以,當我們說INT星級住宿等於 整型malloc的大小,即在那裡, 該箭頭突然出現在 右側有,那整個事情, 我會讓它出現 再次,是什麼情況。 所有這一切都發生在 該一行代碼。 現在,我們會得到更多一點 簡單的一次。 一個等於符號微米。 你還記得什麼 等於符號m是? 嗯,這是一個獲得M的地址。 還是把更多的示意, 一個點為m。 一個等於灣 行,所以這裡的另一個之一。 A等於灣 這是怎麼回事發生 到圖中這個時間呢? 那麼記得, 賦值運算符的作品 通過分配的價值 從右到左側的值。 因此,而不是一個指向米,現在 指向同一個地方,乙組分。 一個沒有指向B,A 指出其中B點。 如果尖到b那會 是一個等於符號灣 而是一個等於b剛 意味著和b是現在 指向相同的地址,因為 的B內僅有一個地址。 現在的一個內是相同的地址。 m等於10,可能的 最簡單的事情 我們在一點點實現。 把10箱。 星級住宿等於M PLUS 2,從召回 我們的三分球視頻什麼明星B表示。 我們將取消引用b和認沽 在該存儲單元的一些值。 在這種情況下,12。 因此,當我們取消引用點 記得我們剛出差向下的箭頭。 或者換一種說法,我們 去那個內存地址 和我們操縱它以某種方式。 我們把一些價值在裡面。 在這種情況下,星級住宿 等於M PLUS 2只 去變量指向B, 到內存指向B, 並把M PLUS 2在那裡,12。 現在,我游離B。 當我游離B,會發生什麼? 還記得我說的自由的手段。 我說什麼時候我游離B? 我做的工作呢,對吧? 我基本上放棄了記憶。 我給它回系統。 我不需要這個了是 就是我要告訴他們,好不好? 現在,如果我說明星 等於11,你大概可以 已經告訴壞事 將要發生在這裡,對不對? 事實上,如果我想,我大概 將遭受分割故障。 因為現在,雖然 內存以前是塊 是的東西,我有 訪問,在這一點 現在我訪問內存 是不合法的,我來訪問。 當我們大概會 還記得,當我們訪問內存 我們不該碰, 這是最常見的原因 一個分割 故障。所以我的計劃 會崩潰,如果我試圖做到這一點。 所以,這又是一個好主意,以獲得良好的 實踐和良好的生活習慣根深蒂固 用malloc和free工作時, 這樣你就不會遭受分割 ,而您使用的故障 您的動態分配 內存負責任。 我是道格·勞埃德這是CS50。