Linux內(nèi)存單位

image.png

image.png

image.png

image.png
- 棧區(qū):占用內(nèi)存大小 最大值: 大概 2M 大于2M會(huì)棧溢出 平臺(tái)有關(guān)系的
- 堆區(qū):占用內(nèi)存大小 最大值: 大概80% 40M沒(méi)有任何問(wèn)題,基本上不用擔(dān)心 堆區(qū)很大的
// malloc 在堆區(qū)開(kāi)辟的內(nèi)存空間 , (動(dòng)態(tài)的范疇) ,C的開(kāi)發(fā)過(guò)程中,不能出現(xiàn),野指針,懸空指針
void dynamicAction() {
int * p; // 野指針 沒(méi)有地址的,空的
// void * 可以任意轉(zhuǎn)變 int* double *
int * arr = malloc(4 * 1024 * 1024); // 1024x1024字節(jié),堆區(qū)開(kāi)辟 4M
printf("dynamicAction函數(shù),arr自己的內(nèi)存地址:%p,堆區(qū)開(kāi)辟的內(nèi)存地址:%p\n", &arr, arr);
// C工程師,堆區(qū)開(kāi)辟的空間,必須釋放
free(arr); // 釋放掉
arr = NULL; // 重新指向一塊內(nèi)存地址00000
printf("dynamicAction函數(shù)2 堆區(qū)開(kāi)辟的內(nèi)存地址:%p\n", arr); // 懸空指針
}
// 字符串
int mainT2() {
char str[] = {'D', 'e', 'r', 'r', 'y', '\0'};
str[2] = 'z'; // 這里能修改?
printf("第一種方式:%s\n", str); // printf 必須遇到 \0 才結(jié)束
char * str2 = "Derry"; // 隱士 Derry+\0
str2[2] = 'z'; // 會(huì)奔潰
printf("第二種方式:%s\n", str);
return 0;
}
C運(yùn)行單位
- C是以函數(shù)作為基本單元,并且從上往下進(jìn)行執(zhí)行,所以函數(shù)A調(diào)用函數(shù)B的時(shí)候需要先將函數(shù)B寫(xiě)在函數(shù)A前面,為了方便開(kāi)發(fā)所以出現(xiàn)了頭文件進(jìn)行函數(shù)聲明,然后在實(shí)現(xiàn),這樣可以先引入聲明文件就可以不用區(qū)分函數(shù)的先后順序。
- JAVA 是以類(lèi)作為基本單位進(jìn)行編輯,所以在類(lèi)里面函數(shù)不分先后都可以找到并執(zhí)行。
指針
- 指針是存放對(duì)應(yīng)變量的地址,可以通過(guò)指針在改變變量的值
- 指針優(yōu)先級(jí) ()> [] > *
指針函數(shù) 函數(shù)指針
- 指針函數(shù)就是返回值為指針的函數(shù)。
- 函數(shù)指針是聲明函數(shù)類(lèi)型的變量,可以將對(duì)應(yīng)的函數(shù)賦值給這個(gè)變量。

image.png

image.png
數(shù)組
- 可以用一個(gè)指針指向數(shù)組首地址,這樣可以通過(guò)指針操作數(shù)組,數(shù)組的內(nèi)存地址 == 第一個(gè)元素的內(nèi)存地址 == &arr

image.png

image.png

image.png
指針數(shù)組
數(shù)組的每個(gè)元素存放的都是指針

image.png
數(shù)組指針
數(shù)組指針一般是行指針,實(shí)質(zhì)上可以用做表示多維數(shù)組


image.png
共用體

image.png
共用體的內(nèi)存占用是根據(jù)成員里面最長(zhǎng)的那個(gè)決定的,而結(jié)構(gòu)體是多個(gè)成員加起來(lái)的總和
//共用體聲明
union Data{
int I;
float f;
char str[2];
} data;

image.png
結(jié)構(gòu)體
- 將多個(gè)變量封裝成一組稱(chēng)為結(jié)構(gòu)體
-
結(jié)構(gòu)體聲明后可以不用像java那樣實(shí)例化,可以直接使用 + 給結(jié)構(gòu)體分配內(nèi)存的時(shí)候是遵循內(nèi)存對(duì)齊的規(guī)則(因?yàn)椴挥脙?nèi)存對(duì)齊,訪問(wèn)一個(gè)變量會(huì)訪問(wèn)兩次來(lái)拼湊一個(gè)完整有效數(shù)據(jù),為了提高執(zhí)行效率,所以用了內(nèi)存對(duì)齊,比結(jié)構(gòu)體中有 int 、short 兩個(gè)變量,實(shí)際上分配內(nèi)存為8個(gè)字節(jié)而不是6個(gè)字節(jié))
image.png
image.png
image.png
image.png
struct Cat {
char name[10];
int age;
};
int main() { // 棧
// 結(jié)構(gòu)體
struct Cat cat = {"小花貓", 2};
// VS的寫(xiě)法:Cat * catp = &cat;
struct Cat * catp = &cat;
catp->age = 3;
strcpy(catp->name, "小花貓2");
printf("name:%s, age:%d \n", catp->name, catp->age);
return 0;
}
int main() { // 堆
// VS的寫(xiě)法:Cat2 * cat = (Cat2 *) malloc(sizeof(Cat2));
struct Cat2 *cat = malloc(sizeof(struct Cat2));
strcpy(cat->name, "金色貓");
cat->age = 5;
printf("name:%s, age:%d \n", cat->name, cat->age);
// 堆區(qū)的必須釋放
free(cat);
cat = NULL;
return 0;
}
struct Workder_ {
char name[10];
int age;
char sex;
};
// VS的寫(xiě)法:typedef Workder_
typedef struct Workder_ Workder_; // 給結(jié)構(gòu)體取別名
typedef Workder_ * Workder; // 給結(jié)構(gòu)體指針取別名
// C庫(kù)的源碼,系統(tǒng)源碼...,為什么 typedef 還取一個(gè)和結(jié)構(gòu)體一樣的名字(兼容代碼的寫(xiě)法,保持一致)
int main() {
// 以前 Clion工具 必須加上 struct VS又不用加 代碼差異化大
// struct Workder_ workder1 = malloc(sizeof(struct Workder_));
// 現(xiàn)在 (兼容代碼的寫(xiě)法,保持一致)
Workder_ workder1 = malloc(sizeof(Workder_));
// VS CLion 他們都是一樣的寫(xiě)法
Workder workder = malloc(sizeof(Workder_));
return 0;
}
庫(kù)文件(動(dòng)態(tài)庫(kù)、靜態(tài)庫(kù))

image.png

image.png

image.png

image.png
APK 中一般用動(dòng)態(tài)庫(kù)比較多,考慮的主要是apk的大小



