C語言字串 堆記憶體

2021-10-25 07:39:14 字數 2884 閱讀 6525

是程序的乙個記憶體段(text\data\bss\heap\stack),由程式設計師手動管理

特點:足夠大,缺點:使用麻煩

1、隨著程式的複雜,資料量變多

2、其它記憶體段的申請、釋放不受控制,堆記憶體的申請和釋放受控制

注意:c語言中沒有控制堆記憶體的語句,只能使用c標準庫提供的函式

#include void *malloc(size_t size);

功能:從堆記憶體中申請size個位元組的記憶體,申請到的記憶體中儲存是什麼內容不確定

注意:不會把記憶體塊的資料全部清0

void free(void *ptr);

功能:釋放一塊堆記憶體,可以釋放null,但是不能重複釋放和釋放非法記憶體

注意:釋放的只是使用權,裡面的資料不會特意的全部清理

void *calloc(size_t nmemb, size_t size);

功能:從堆記憶體中申請nmemb塊大小為size的位元組的記憶體,申請到的記憶體塊會被初始化為0

注意:申請到的還是一塊連續的記憶體塊

void *realloc(void *ptr, size_t size);

功能:改變已有的記憶體塊的大小,size表示調整後的大小,大小在原有的基礎上調大或調小

如果無法在原有記憶體塊的基礎上調整:

1、申請一塊符合大小要求的記憶體塊

2、把原記憶體的資料拷貝過去

3、把原記憶體塊釋放,返回新記憶體塊的首位址

當首次向malloc申請堆記憶體時,malloc會向作業系統申請記憶體,作業系統會直接分配33頁(1頁=4096位元組),交給malloc管理。

但不以為著可以越界,因為malloc把使用權會分配各"其他人",這樣就產生了髒資料

每個記憶體塊之間都有空隙(4~12位元組),這些空隙一些是為了記憶體對齊,其中4個位元組記錄了malloc的維護資訊,這些維護資訊決定了下次分配記憶體塊的位置,可以通過借助這個資訊計算出每個記憶體塊的大小,當這些資訊被破壞時,會影響接下來malloc和free的呼叫

使用堆記憶體要注意的問題:

記憶體洩漏:

記憶體無法再使用,也無法釋放,再次使用時只能重新申請,然後重複以上過程,是日積月累導致系統中可用的記憶體越來越少

注意:程式一旦結束屬於它的所有資源都會被作業系統**

如何盡量避免記憶體洩漏:

誰申請的誰釋放,誰知道該釋放誰釋放

如何判斷定位洩漏:(搜一下)

1、檢視記憶體的使用情況

2、分析**,使用**分析工具檢查malloc使用情況

3、包裝malloc、free,申請、釋放資訊記錄到日誌中

記憶體碎片:

已經釋放但無法再繼續使用的記憶體叫做記憶體碎片,是由申請和釋放的時間不協調導致的,而且無法避免,只能儘量減少

如果減少記憶體碎片:

1、盡量使用棧記憶體

2、不要頻繁地申請釋放記憶體

3、盡量申請大塊記憶體自己管理

#include void bzero(void *s, size_t n);

功能:把一塊記憶體清理為0

s:記憶體塊的首位址

n:記憶體塊的位元組數

#include void *memset(void *s, int c, size_t n);

功能:把記憶體塊按位元組設定為c

s:記憶體塊的首位址

c:想要設定的ascii碼值

n:記憶體塊的位元組數

指標陣列:定義n*m二維陣列

型別* arr[n];

型別* arr[n] = {};

for(int i=0;i字元

:字元就是符號或圖案,在計算機中字元是以整數形式存在的,當需要使用是會根據ascii碼表中的對應關係來顯示相應的符號或圖案。

0 『\0』

48 『0』

65 『a』

97 『a』

串:是一種資料結構,由一組連續的若干個相同型別的資料組成。

末尾有乙個結束標誌。

對於串型結構的處理都是批量性,從開頭位置直到遇到了結束標誌停止。

字串:
由字元組成的串型結構,結束標誌是'\0'
char *gets(char *s); 

功能:輸入字串,並且可以接收空格

返回值:鏈式呼叫(把乙個函式的返回值,作為另乙個函式的引數)

char *fgets(char *s, int size,stdin);

功能:可以設定輸入的字串的長度size-1,超出部分不接收,強制在末尾為'\0'預留位置

int puts(const char *s);

功能:輸出乙個字串,會在末尾自動新增\n

返回值:成功輸出的字元個數

字串的存在形式:

字元陣列:char arr[10] = ;

由char型別組成的陣列

注意:主動為\0 預留位置

使用的是棧記憶體,資料可以修改

字串字面值

"由雙引號包含的若干個字元",預設末尾加上\0

字串字面值是以位址形式存在的,儲存在**段,如果強行修改就會產生段錯誤

const char* str = "字串字面值";

sizeof("strstr") 輸出 字元個數+1

注意:兩個一模一樣的字串字面值在**段中只有乙份

常用方式:

字串陣列 = "字串字面值";

char str = "hello world!";

會自動為\0預留位置,而且可以修改值。

賦值完後字串存在兩份,乙份儲存在**段,另乙份在棧記憶體(這份可以修改)

學習筆記12 C語言 堆記憶體 字串

是程序中的乙個記憶體段 text data bss heap stack 由程式猿手動控制。特點是足夠大,缺點是使用麻煩1 隨著程式的複雜,資料會越來越多。2 其他的記憶體段的申請和釋放不受控制,堆記憶體的申請釋放受程式猿控制注意 在c語言中沒有控制堆記憶體的語句,只能使用c標準庫中的函式 void...

C語言指標 字串 記憶體

char p hello world 稱為a定義方式 char p hello world 稱為b定義方式 兩個p的區別 分兩種情況 1 這個p是全域性變數 通俗點就是在函式外面定義的 那麼這兩種方式,產生的效果有點相同的地方 a 使用a定義方式,只分配了 sizeof p sizeof hello...

C語言字串 字串排序

本題要求編寫程式,讀入5個字串,按由小到大的順序輸出。輸入為由空格分隔的5個非空字串,每個字串不包括空格 製表符 換行符等空白字元,長度小於80。按照以下格式輸出排序後的結果 after sorted 每行乙個字串 red yellow blue green white after sorted b...