指標和陣列(一維,二維,三維)以及野指標的避免

2021-07-15 05:49:14 字數 3797 閱讀 6135

如何避免野指標?

答:①當指標未指向時,一般將指標置為空

②當想向指標指向空間賦值時,為其分配空間。當用malloc

為其分配空間的時候,要看其是否分配成功(注意清空原來的緩衝區),函式執行完以後,需要用

free

(ptr

),用完後再賦值為

null

(ptr=null)

初始化為null

的目的:①該指向

0位址,操作不能在

0位址操作②當出現段錯誤的時候,容易改錯,方便除錯

(null

為巨集,#define null

(void *)0

代表0位址,0

位址是不允許操作和訪問的)

malloc分配空間:

ptr=(char *)malloc(max_size*sizeof(char))

()加強制型別轉換是為了:該必須是相同的

void *:表示萬能指標(可接收任何指標型別,但不能進行取值,不能對位址指向空間操作)

指標-

陣列  [ ]=*( )

一維陣列(char *p=a)

&a:對一維陣列的陣列名取位址等於陣列的位址 *(

&a (int (*pa)[max_size]=&a)

二維陣列(行可省略)

int a[i][j]

a代表首個一維陣列的位址

①scanf(「%d」,&a[i][j])    printf(「a[%d][%d]=%d\n」,i,j,a[i][j])

②scanf(「%d」,*(a+i)+j)    printf(「a[%d][%d]=%d\n」,i,j,*(*(a+i)+j)

傳二維陣列名用一維陣列指標來接(void ch(char (*src)[100])

a+i:第

i+1個一維陣列的位址

*(a+i):第

i+1個一維陣列的首元素位址

*(a+i)+j:第

i+1個一維陣列的第

j+1個元素的位址

*(*(a+i)+j):第

i+1個一維陣列的第

j+1個元素的值

三維陣列(二維陣列指標)

*(&a)=a

*(*(*(a+i)+j)+k)

a+i:第

i+1個二維陣列的位址

*(a+i):第

i+1個二維陣列的首個一維陣列的位址

*(*(a+i)+j:第

i+1個二維陣列的第

j+1個一維陣列的首元素的位址

*(*(a+i)+j)+k:第

i+1個二維陣列的第

j+1個一維陣列的第

k+1個元素的位址

*(*(*(a+i)+j+k):第

i+1個二維陣列的第

j+1個一維陣列的第

k+1個元素的值

傳指標陣列時,用指標的指標:void print_ptr(char **ptr)

malloc,realloc,calloc的宣告:

void* realloc(void* ptr, unsigned newsize); 

void* malloc(unsigned size); 

void* calloc(size_t numelements, size_t sizeofelement); 

分別什麼時候使用?

malloc用於申請一段新的位址,引數

size

為需要記憶體空間的長度

calloc與

malloc相似,

引數sizeofelement

為申請位址的單位元素長度

,numelements

為元素個數

realloc是給乙個已經分配了位址的指標重新分配空間,引數

ptr為原有的空間位址

,newsize

是重新申請的位址長度

三者的區別:

malloc呼叫形式為(型別

*)malloc(size)

:在記憶體的動態儲存區中分配一塊長度為「

size

」位元組的連續區域,返回該區域的首位址。

calloc呼叫形式為(型別

*)calloc(n

,size)

:在記憶體的動態儲存區中分配

n塊長度為

「size」

位元組的連續區域,返回首位址。

realloc呼叫形式為(型別

*)realloc(*ptr

,size)

:將ptr

記憶體大小增大到

size。

malloc函式原理:

malloc函式有乙個將可用的記憶體塊連線為乙個長長的列表的所謂空閒鍊錶,呼叫malloc函式時,它沿連線表尋找乙個大到足以滿足使用者請求所需要的記憶體塊,然後將該記憶體塊一分為二(一塊的大小與使用者申請的大小一樣,另一塊就是剩下的位元組),接下來,將分配給使用者的那塊記憶體傳給使用者,並將剩下的那塊(如果有的話),返回到鍊錶上,呼叫free函式 時,它將使用者釋放的記憶體塊連線到空鏈上,到最後,空閒鍊錶會被切成很多的小記憶體片段,如果這時使用者申請乙個大的記憶體片段,那麼空閒鏈上可能沒有可能滿足使用者要求的片段了,於是malloc函式請求延時,並開始在空間中翻箱倒櫃的檢查記憶體片段,對它們進行整理,並將相鄰的小空閒塊合成較大的記憶體塊

陣列與指標的區別:

區間分配:

①陣列要麼在靜態儲存區被建立,要麼在棧上被建立。陣列名對應著一塊記憶體,其位址與容量在生命期內保持不變,只有陣列的內容可以改變。

指標可以隨時指向任意型別的記憶體塊,它的特徵是「可變」,所以我們常用指標來操作動態記憶體。

②不能對陣列名進行直接複製與比較

訪問效率:

通過 a 訪問,系統只需要計算常量 a 與 i*sizeof(type) 之和,然後訪問該位址

通過 p 訪問,p 是個變數,系統必須先訪問 p 的位址,得到 p 的值,然後計算該值 v(p) 與 i*sizeof(type) 之和, 然後再訪問得到的位址。 

相比之下,指標要稍微慢一些,在絕大多數情況下,指標與陣列相比,沒有效率上的優勢,有時反而更慢。指標的真正優勢是靈活,好用。

函式傳參:

陣列在作為函式傳參時,陣列名將蛻化為指標,

二維陣列的儲存方式是和一維陣列沒什麼區別,但是用二維陣列做引數,要注意的是:函式中的形參其實就相當於乙個宣告,並不產生記憶體分配,形參的目的就是要讓編譯器知道函式引數的資料型別

指標傳參傳遞的是一引數(這裡是int實參)的位址,這樣,雖然實參和形參不一樣,但是它們只想的位址是一樣的,所以對相同位址的數的操作會影響到原來的數。

安全性:

指標可能會重複釋放,而且會產生野指標,從而導致記憶體的洩漏;也有可能導致堆緩衝區溢位

二維數 三維陣列

二維陣列 2017 11 10 對比 1 概念 一維陣列 存貯一組相同型別資料 二維陣列 存貯著多個一維陣列 類推 三維陣列 存貯著多個二維陣列 2 宣告 一維陣列 陣列型別 陣列名 初始值 int arr01 int arr00 new int 5 二維陣列 陣列型別 陣列名 初值 陣列型別為一維...

陣列(Array),二維陣列,三維陣列

陣列 array 相同型別資料的集合就叫做陣列。一 定義陣列的方法 a type 變數名 new type 陣列中元素的個數 例如 int a new int 10 或者 int a new int 10 b type 變數名 new type 例如 int a new int 二 陣列的lengt...

如何建立二維三維陣列

ps 一維陣列是指標,可將二維陣列看作是指標的指標 每一行是乙個一維陣列,而列是指向行的指標。在動態建立時,先分配指向行的指標空間,再迴圈維每一行申請空間。二維 建立 int p p new int x 行 申請行的空間 每行的列申請空間 for i 0 i三維 建立 int p3 p3 new i...