指針、指針變量與內存空間——解惑

指針、指針變量與內存空間——解惑

一年前,我曾今在ChinaUnix寫過一篇博客《關於定義一個指針與指針變量》然後搬家來了CSDN。這篇博客中寫道了很多關於指針和指針變量以及空間分配的一些常見錯誤。但是,到現在爲止,無論是CSDN的網友還是一些已經工作的同事以及大三大四的學生,陸陸續續的有人在問我關於指針與指針變量還有空間分配問題。我想在這裏再寫一篇博客解惑指針

問題1

view plaincopy to clipboardprint?
int idata = 5;
int *p = idata//爲什麼這裏不對?

既然通常*p表示對指針p指向數據的引用,爲什麼*p = idata不能行呢?

回答:int *p和引用時的*p概念是不一樣的。定義數據的時候 int *p所表示的是定義了一個指向int數據的指針p。並不是數據引用時的*p.

所以,int *p只是定義了一個指向int數據的指針p,這個指針p所存放的是一個地址(32位),而idata是一個int數據,int數據不能賦值給一個地址。除了定義以外的其他地方,*p所表示就是p所指向的數據。

所以以上語句作出以下更改就對了:

view plaincopy to clipboardprint?
int idata = 5;
int *p = &idata;//p存放idata的地址

問題2:

既然問題1中已經說了,定義是隻是定義了一個指針p,下面的語句爲什麼是對的呢?

view plaincopy to clipboardprint?
char *p = "hello world";//爲什麼是對的?

回答:

C語言中,字符字符串常量是按字符串數組來處理的,會在內存中開闢一個字符串數組用來存放該字符串常量,然後把該字符串數字的首元素地址賦值給p。

以上語句其實等價於下面:

view plaincopy to clipboardprint?
char *p = "hello world";
//等價於
char tmp[] = "hello world";
char *p = tmp;
//等價於
char tmp[] = "hello world";
char *p = NULL;//初始化,避免編譯錯誤
p = tmp;

問題3:

對於結構體指針,struct mystruct *pstruct,然後對pstruct進行操作,爲什麼有時候正確,有時候又報內存錯誤?

回答:

指針的操作分爲輸入與輸出。所謂輸入:即將指向結構體的指針pstruct穿進去給別人處理。輸出:即別的函數需要輸出,需要寫的。

你所謂的有時候正確有時候又不正確,其實是因爲你沒有搞清楚究竟該誰分配空間。一定要銘記:定義一個指針只是定義了一個存放地址的指針變量,他只能存放地址,定義一個指針並沒有爲他所指向的數據分配空間。例如 struct mystruct *p,定義了一個指向struct mystruct的指針變量p,並沒有分配struct mystruct大小的數據空間。如果p沒有指向任何數據,你對它進行寫操作,必定會出內存錯誤。

但是如果這樣做:

struct mystruct myst;

struct mystruct *p = &myst;

然後再對p進行操作,就不會出錯。說到底,還是沒有弄清楚程序設計需要誰去爲數據分配空間的問題。

最近在溫故《C ++ primer》這本書,其中有一句話非常經典:

When attempting to understand pointer declarations, read them
from right to left.

理解指針定義的時候,應該從右往左讀

定義變量是由系統自動申請的,比如定義int i;系統自動申請一個整型變量的內存空間,定義指針只是申請一個指針的空間(一般是2字節),指向的位置需要自己申請,或指向一個已經由系統申請的空間,自己申請的必須自己free掉,系統申請的函數調用完後系統自動釋放

在函數定義指針或者變量已經爲指針本身和變量本身分配了內存所以用指針指向一個已經定義的變量時不需再分配內存
但是數據結構中用指針指向結構體時只爲指針本身分配了內存如果要對結結構體填入內容就要分配一個結構體大小的內存纔可以
但只自己分配的內存一定要養成用free()的好習慣
比如說定義一個結構體
struct node{
int man;
int what;
}ok;
定義一個指針
struct node *p;
此時p就可以對結構體進行操作但非常危險因爲沒有對p初始化以下兩種都是初始化
p=&ok;//這裏就不用分配內存了原因就是上面所說的
p=(struct node *)malloc(sizeof(struct node));
現在p纔可以安心的使用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章