C語言中的記憶體分配深入 二

2021-08-22 15:40:14 字數 2963 閱讀 9679

int *p , a, b;

p = &a;

p = &b;

即便是ab都沒有分配值,但是它的位址是存在的;

第二、上面的那種情況是有侷限性的,他的成立條件就是系統已經給這個指標分配好4個位元組的情況,因此,也並不是所有的指標都可以任意指向,當乙個指標以另外乙個物件的指標的形式存在的時候,指標的4個位元組是確定的了,同情況一,但是作為指標的內部指標存在的時候,分給指標的4個位元組的空間就不是那麼的明朗了,這個時候就牢記一點,這個4個位元組也是指標的內部值,在沒有大的指標分配位址空間的時候,內部依舊不可以寫,那麼這個小的內部指標也是不可以寫的,因此它不可以指向任何位址!

#include #include typedef struct sim sim ;

int main()

#include #include typedef struct sim sim ;

int main()

因此還是那句話,指標沒有分配位址空間的時候,內部不可寫!

我們看乙個鍊錶的錯誤的刪除操作,而且這種操作我在好多地方見過,如下: //

……}

這裡問題就出來了,

current

被free

之後,他的

next

還可以指向他之前指向的那個物件否?那他的自帶的值還可以被寫否?

前者是否定的,後者是不一定,一般的情況甚至是肯定的。

首先補充一點,就是乙個指標也特別結構體指標,在沒有分配位址空間的時候,不管是物件還是指標都是不可以寫的,指標可以寫null。如下,malloc的標頭檔案在vs2005要代malloc.h標頭檔案,linux的gcc編譯器只要stdio.h就可以了:

#include

<

stdio.h

>

#include

<

malloc.h

>

typedef

struct

************;

intmain()

這個程式在vs2005裡面執行就是乙個很響亮的「當」,linux下就是程式中斷得到乙個段錯誤。

回到上面的問題,既然free了那就相當於沒有分配空間,肯定也就不能寫哦,為什麼答案是可以寫呢(一般情況下)?

這樣,我們建立乙個小煉表,就兩個物件,a和b,讓a的next指向b,然後free釋放a,再看看:

#include

<

stdio.h

>

#include

<

malloc.h

>

typedef

struct

************;

intmain()

程式輸出:

theaddrofa

is3887080

!theaddrofb

is3876984

!theaddrofc

is3877040

!theaddrofa

->

next

is3876984

!thenumberofa

->

test

is100

!theaddrofa

->

test

is3887080

!theaddrofa

is3887080

!theaddrofb

is3876984

!theaddrofc

is3877040

!theaddrofa

->

nextis-

572662307

!thenumberofa

->

testis-

572662307

!theaddrofa

->

test

is3887080

!theaddrofc

is3877040

!test

is200

在這個程式裡面我們就看到了,

free

之前,a

的內容如下:

the addr of a->next is 3876984 !

the number of a->test is 100 !

the addr of a->test is 3887080 !

free之後,內容如下:

the addr of a->next is -572662307 !

the number of a->test is -572662307 !

the addr of a->test is 3887080 !

test和next的值都已經變化了,但是從test的位址可以看出a並沒有從原來的位址「撤兵」,他依舊指向他以前的位址,但是有一點很明顯就是a裡面的所有的值都已經變化,而且是很奇怪了。

這裡就回答了前面的兩個問題,free之後的物件不再指向他原來的值,但是他依舊可以寫,但是,如果他用的這個內存在此被分配給別的變數的時候,就不再可寫了。

再回到最上面的delete操作,再上面的這段程式裡面加點東西,讓a的位址變為a的next,開始已經知道了,next已經變了,但是還是可寫的。

如下:#include

<

stdio.h

>

#include

<

malloc.h

>

typedef

struct

************;

intmain()

這樣一來,在執行到

a->next = c

的時候程式崩潰,

a指向了乙個不可寫的位址,

a = a->next

不會崩潰,因為這裡只是改變了乙個位址值,而不是寫記憶體。

解決方案:

對於free了的指標,我們補上一句話,用null給它賦位址!

C語言中記憶體分配

一 static在c語言裡面可以用來修飾變數,也可以用來修飾函式。1 先看用來修飾變數的時候。變數在c語言裡面可分為存在全域性資料區 棧和堆裡。其實我們平時所說的堆疊是棧而不是堆,不要弄混。例如 在file.c中 int a int main int b int c int malloc sizeo...

C語言中的記憶體分配

1 段 text 裡面儲存的是可執行程式的二進位制指令,為了防止被意外修改,段一般是唯讀的 2 全域性段 資料段data 儲存被初始化過的全域性變數 靜態變數 3 bss段 靜態資料段 儲存靜態變數 被static修飾過的變數 和末初始化的全域性變數,這段內存在程式執行前會被初始化為0 4 堆 he...

C語言中記憶體分配問題

推薦 c語言中記憶體分配 linux size命令和c程式的儲存空間布局 本大神感覺,上面的鏈結的內容,已經很好的說明了 對於乙個可執行檔案,在linux下可以使用 size命令列出目標檔案各部分佔的位元組數 分為 text段 data段與bss段 參考 linux size命令和c程式的儲存空間布...