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

2021-10-13 12:38:04 字數 4866 閱讀 6299

是程序中的乙個記憶體段(text\data\bss\heap\stack),由程式猿手動控制。

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

1、隨著程式的複雜,資料會越來越多。

2、其他的記憶體段的申請和釋放不受控制,堆記憶體的申請釋放受程式猿控制

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

void *malloc(size_t size);

malloc(4);

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

size: 表示要申請的位元組數大小

void free(void *ptr);

注意:釋放的只是使用權,不會專門去清理全部的資料

void *calloc(size_t nmemb,size_t size)

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

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

void *realloc(void *ptr,size_t size)

功能:改變已有的記憶體的大小,在原來記憶體大小的基礎上調大或調小

size:表示調整後的大小

如果無法在原來的基礎上進行調整:

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

2、把原記憶體塊中的資料拷貝到新記憶體塊中

3、把新記憶體塊的首位址返回

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

但是不意味著你可以越界訪問,因為malloc可能會把使用權分配給「其他人」,這就會導致髒資料。

每個記憶體塊之間都會有一些空隙(4~12個位元組),這些空隙一些是為了記憶體資料對齊,其中一定會有4個位元組是用於記錄malloc維護資訊,

這些維護資訊決定了malloc下次分配記憶體的位置,以及借助這個維護資訊計算出每個記憶體塊的大小,當這些資訊被破壞時,會影響下一次和freemalloc函式的呼叫

記憶體洩露:

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

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

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

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

如何判斷定位記憶體洩漏:

1、檢視記憶體使用情況windows下看任務管理器,linux下使用ps -aux命令檢視記憶體使用情況)

2、使用**分析工具來檢查malloc和free的呼叫情況

3、包裝malloc和free函式,記錄申請釋放記憶體資訊到日誌中

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

如何減少記憶體碎片:

1、盡量使用棧記憶體

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

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

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

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

n: 要清理的記憶體塊的位元組數

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

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

c:xiangyao設定的字元的ascii碼值

n: 要清理的記憶體塊的位元組數

指標陣列:

定義n*m的二維陣列

型別* arr[n];

for(int i=0;i練習1:計算出100~10000之間的所有素數,結果要儲存再堆記憶體中,不能浪費記憶體

#include

#include

#include

#include

bool is_ss

(int n)

return true;

}int

main

(int argc,

const

char

* ar**)

}for

(int i=

0;i)free

(p);

p=null

;return0;

}

字元:

在計算機中,字元是以整數形式儲存再記憶體中,當需要顯示為字元時,會根據ascii碼表中的對應關係來顯示出相應的符號與圖案。

'\0' 0

'0' 48

'a' 65

'a' 97

字元的輸入:

scanf("%c",&ch);

ch = getchar();

字元的輸出:

printf("%c",ch);

putchar(ch);

串: 是一種資料結構,是由一組連續的若干個相同型別的資料組成,末尾有乙個結束標誌。

對於這種資料結構的處理都是批量性的,從開頭位置開始直到結束標誌為止。

字串:

由字元組成的串型結構,結束標誌是'\0'

字串的輸入:

scanf %s 位址

注意: 不能接受空格

char *gets(char *s);

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

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

char *fgets(char *s,int size,file *stream);

功能:可以設定輸入的字串的長度為size-1,超出部分不接受,會為'\0'預留位置。

注意:如果輸入的字元數不足size-1個,,最後的'\n'會一起接受

char str[20]={};

fgets(str,20,stdin);

字串的輸出:

printf %s

int puts(const char *s);

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

返回成功輸出的字元個數

字元陣列: char str[10] = 

由char型別組成的陣列,要為'\0'預留位置

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

字串字面值:「hello world!」

"由雙引號包含的若干個字元",會在末尾隱藏乙個\0

字串字面值是以位址形式存在的,資料是儲存再**段,如果修改則會產生段錯誤

const char* p = 「字串字面值」;

sizeof("strstr");結果 = 字元個數+

兩個一摸一樣的字串字面值在**段中只儲存乙份

常用方式: 字元陣列="字串字面值";

會自動為'\0'預留位置

注意:在賦值完成後字串就存在了兩份,乙份儲存在**段,乙份儲存在棧記憶體(可修改)

練習2:實現乙個函式,判斷字串是否是回文數

#include

#include

#include

bool is_hw

(const

char

* n)

return true;

}int

main

(int argc,

const

char

* ar**)

;gets

(num);if

(is_hw

(num)

)printf

("yes");

else

printf

("no");

}

練習3:實現乙個函式,把由數字字元組成的字串轉換為整數

#include

#include

void

to_num

(char

* n,

int l)

}int

main

(int argc,

const

char

* ar**)

;gets

(num)

;int len =

strlen

(num)-1

;to_num

(num,len)

;for

(int i=

0;i<=len;i++

)}

練習4:實現乙個函式,把字串逆序、

#include

#include

void

change

(char

* n,

int l)

}int

main

(int argc,

const

char

* ar**)

;gets

(str)

;int len=

strlen

(str)-1

;change

(str,len)

;puts

(str)

;}

練習5:實現乙個**函式,10人名單,按隨即順序列出人名

#include

#include

#include

#include

intmain

(int argc,

const

char

* ar**)

;for

(int i=

0;i<10;

)}}

C語言字串 堆記憶體

是程序的乙個記憶體段 text data bss heap stack 由程式設計師手動管理 特點 足夠大,缺點 使用麻煩1 隨著程式的複雜,資料量變多 2 其它記憶體段的申請 釋放不受控制,堆記憶體的申請和釋放受控制注意 c語言中沒有控制堆記憶體的語句,只能使用c標準庫提供的函式 include ...

CareerCup之1 2C風格字串翻轉

題目 原文 write code to reverse a c style string.c string means that abcd is represented as five characters,including the null character.譯文 寫 翻轉乙個c風格的字串。c...

學習筆記 C語言 字串陣列

1.使用場合 一維字元陣列中存放乙個字串,比如乙個名字char name 20 mj 如果要儲存多個字串,比如乙個班所有學生的名字,則需要二維字元陣列,char names 15 20 可以存放15個學生的姓名 假設姓名不超過20字元 如果要儲存兩個班的學生姓名,那麼可以用三維字元陣列char na...