《嵌入式LINUX與物聯網軟件開發 C語言內核深度解析》學習1——C語言與內存

什麼是程序?

程序=數據+算法。

內存分類:

分靜態內存SRAM、動態內存DRAM。
DRAM有好多代,比如DDR1、DDR2、DDR3、DDR4……。

內存結構:

1、馮諾依曼結構:代碼和數據存儲在同一個存儲器中,並且共用一條傳輸總線,因此影響到了數據處理速度。
2、哈佛結構:指令和數據分開存儲的結構。執行效率高。
這兩種結構各有各的用處。

程序爲什麼要有內存

用來存儲數據

幾種語言對內存的管理

1、彙編:沒有內存管理,直接操作地址(例如0xd0020010)。
2、c語言:編譯器幫我們管理地址。通過編譯器提供的變量名來訪問內存。程序員可以通過API來申請,注意要自己釋放。
3、C++:和C差不多
4、Java/C#:不直接操作內存,而是通過虛擬機來操作。程序員不需要關心內存的釋放,虛擬機自己會做,但是虛擬機回收內存需要一定的代價。

內存是什麼

內存在邏輯上就是一個個的格子,每個格子都有編號,這個編號就是內存地址。硬件保證了按照這個地址就一定能找到格子。
我們以多大空間來劃分一個格子,並綁定一個地址呢?
以一個字節爲基本單位對整個內存進行劃分,並綁定地址。

linux C的內存映像

在這裏插入圖片描述

數據類型在開闢內存時的作用

c語言中有char、short、int、long、double這些基本數據類型。
當我們定義一個變量時,應該分配多大的空間,按照什麼樣的方式去解析該空間呢?數據類型就決定了分配的空間和解析方法。
(32位系統中最好使用int,因爲硬件本身就是32位的,例如bool型如果定義成int,雖然浪費了31位,但是效率會高很多,所以有人說寫程序要配合硬件特點)
那造成的浪費怎麼辦呢?現在內存很便宜,條件允許的話還是以效率爲重。

爲什麼要內存對齊

內存以4字節對齊時效率比較高。

函數是怎麼找到的

函數名就是一段代碼的封裝,函數名其實就是這段代碼的首地址,也就是說函數名是一個指針。

數組名是什麼

在內存中申請一塊連續的空間。數據名相當於一個指針,裏面存放的是這塊空間的首地址(第一個字節的地址)。
對數據名的+操作,具體偏移多少字節,需要看數組的數據類型。

C實現面向對象(有趣的想法)

struct
{
	int age;    //成員變量
	void (*pFunc)(void);    //成員函數
};
linux系統就是用C寫出來的,但是思想是面向對象的,所以有的人學了C但是看不懂linux內核代碼。

堆棧的理解

堆和棧是兩個東西。都是用於管理內存的。
棧的特點:先進後出,後進先出,空間小,自動分配和回收,存放局部變量。
堆:容量大,人工申請和釋放(malloc,free)。因爲需要人工,有的人記性不好忘記釋放了就內存泄漏了。

內存的管理方式有哪些?

內存被分爲棧、堆、數據段、bss段、text段(代碼區)等不同管理方法的內存段。
有的分類是棧、堆、數據區(.data 和.bss)、常量區(.ro.data)。
1、棧特點
	- 空間自動管理,運行時空間自動分配,運行結束時空間自動回收。棧是自動管理的,程序員不需要手動干預。
	- 能夠反覆使用,棧內存在程序中使用的都是一塊內存空間,程序通過自動開闢和自動釋放會反覆使用這一塊空間。
	- 髒內存,棧內存由於反覆使用,每次使用後程序不會去清空內容,因此當下一次該內存再次被分配時,上一次使用的值會還在。
	- 臨時性,函數不能返回棧變量的指針,因爲這個空間在函數運行結束後會被釋放。
2、堆特點
	- 靈活
	- 內存量大
	- 程序手動申請和釋放
	- 髒內存
	- 臨時性,堆內存在free之後不能訪問,否則會有不可預料的後果
3、數據區和.data和.bss
  	數據區,也叫靜態數據區、靜態區、全局靜態區,存放靜態變量、全局變量的空間。
   	.data存放的是顯示初始化爲非0的靜態數據。
   	.bss存放的是顯示初始化爲0或未顯示初始化的靜態、全局數據。

程序中變量的存儲

加入main.c文件的內容如下:
int a = 0; 				------全局初始化區 
char *p1; 				------全局未初始化區 
main() 
{ 
int b; 					------棧 
char s[] = "abc"; 		------棧 ,有人會覺得"abc"在常量區,其實在編譯的時"abc"會拷貝到s所在的內存區域,拷貝完後就丟棄了
char *p2; 				------棧 
char *p3 = "123456"; 	------123456\0在常量區,p3在棧上。 
static int c =0; 		------全局(靜態)初始化區 
p1 = (char *)malloc(10); 
p2 = (char *)malloc(20); 
分配得來的10和20字節的區域就在堆區。 
strcpy(p1, "123456"); 123456\0放在常量區,編譯器可能會將它與p3所指向的"123456"優化成一個地方。 
}

malloc的一些細節

malloc(0),返回的是NULL還是一個有效指針呢?答案是不確定,由各malloc函數庫的實現者來定義。
malloc(4), GCC中malloc默認最小是以16B爲單位進行空間分配的。如果指定空間小於16B,也會按照16B來分配。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章