2011-07-31 54 views
0

這是一個新手C++指針問題。我不知道爲什麼會發生這種情況......C++:int * j有什麼問題; * J = 50; ?

我發現如果我寫這段代碼。這完全有效。

代碼1

int *j; //create an pointer j 
*j = 50; //assign 50 to the *j, meaning value pointed by address 50 is xxx 

然而,當我想嘗試,使之更加簡單。編譯器給我這個錯誤信息。

代碼2

int *j = 50; //i guess this should be the same with Code1... 

編譯錯誤

error: invalid conversion from ‘int*’ to ‘int’ 

那麼,爲什麼會是這樣呢?

+6

代碼1不是完全有效的,它是完全未定義的行爲。 'j'是一個未初始化的指針。 –

+0

那麼,我的意思是編譯時間 –

回答

13

那裏的C語法有點不明確。

int *j = 50; 

相當於

int *j; 
j = 50; 

事實上,因爲你還沒有值分配給它之前分配對於j任何記憶你在做什麼在代碼的第一個片段是危險的。你需要做的內存爲它就像這樣:

用C

int *j = (int*) malloc(sizeof(int)); 
*j = 50; 

用C ++

int *j = new int; 
*j = 50; 

或者在內存其他一些塊的角度指針已經有效:

int k; 
int *j = &k; 
*j = 50; 
printf("%d", k); // 50 

編輯:值得指出的是,歧義與'*'符號有關。在聲明中,int *j; * j表示「一個名爲j的指針」。但是,當您在第二行「* j = 50」中使用它時,*就成爲解除引用符號,意思是「地址j處的值」。

+1

這是最具說明性的答案 – Jeremy

+0

如果我們沒有在C中分配內存,它會出現什麼危險點?在C++中會危險嗎? –

+3

這兩種語言都會很危險。基本上它是俄羅斯輪盤賭。指針「j」指向內存中一個不確定的位置,並且你在那裏發射一個子彈(實際上是一個5)。正確的用法是讓'j'指向某個地方,可以讓你的子彈沒有任何人受傷。 –

2

它們有不同的含義。

第一個聲明一個指針,並將當前位於j的地址指向的int設置爲50。沒有其他的背景,這已經很糟糕了。 j中的地址未初始化,因此通過將值寫入內存中的隨機位置很可能導致分段錯誤。

第二一段代碼聲明一個指針,並定義存儲在它50.如果你分開它的地址,它酷似寫入(請注意在第二條語句中缺少一個星號):

int *j; j = 50; 
+0

但爲什麼第二段代碼會出現編譯錯誤?那麼在'* j = 50'中,它意味着將50指定給j指向的地址? 'j = 50'意思是把50分配給j的地址? –

+0

我不知道。當我嘗試時,這兩個示例編譯沒有錯誤。 –

+0

我是g ++版本下的gcc版本4.4.1 –

1

你的兩個例子都是錯誤的。

第一:

int *j; 
*j = 50; 

50的地址j。但是,您從未初始化過j,因此您只是將其存儲到未知地址。有時這會「成功」,有時這會讓你的應用程序崩潰,有時它只會破壞應用程序狀態而不會導致錯誤;這絕不是你想要做的。

第二種:

int *j = 50; 

嘗試初始化類型的變量「指針到整數」與類型「INT」,這是一個錯誤的值。

相反,你想要做的事,如:

int i = 50; 
int *j = &i; // j is now a pointer to i. 

或:

int i; 
int *j; 
j = &i; // note: no * before j. j now contains a valid address. 
*j = 50; // store 50 to the address j. After this, i == 50. 
0
int *j = 50 

實際上等於給

int *j; 
j = 50; 

因爲在初始化分配新建分配FY分配變量無論如何itsel。

在這兩種情況下,這是一個非常糟糕的主意,因爲指針是無效的。

2

在聲明int *j;之後,int *類型的空間被分配在堆棧上(在這種情況下),它具有一些地址addr_stk和我們不知道的內容,即。垃圾。

+--------+   +--------+ 
| ??? |----+  | xxx |  trying to store 50 here 
+--------+ |  +--------+ 
| j | |  |  | 
+--------+ |  +--------+ 
|addr_stk| +---->| ??? |  have no permission to access this location 
+--------+   +--------+ 

當使用*j = 50;指針變量的內容(對象)j被用作地址到值存儲50在那裏。因此,您試圖將值50存儲在具有垃圾地址值的某個地址位置,這意味着它可能位於任何位置。無論何時您嘗試訪問未分配給您的內存位置都無法存儲或訪問該位置,操作系統將會阻止您,並導致錯誤。

你需要做的是首先用一些有效的地址初始化指針變量j。這可以通過首先分配一些內存malloc然後使用它來完成。或用其他變量(本地或全局)的地址初始化j。像

int *j, i; 
j = &i; 
*j = 50; 

int *j; 
j = malloc (sizeof (int)); 
*j = 50; 
在兩者的情況下

訪問*j當我們有內部j有效的地址,因此使用的j的內容作爲地址(指針接入),是有效的,因爲*j做出決議到有效的內存訪問。

重要的是,當你用malloc分配內存時,你應該總是釋放內存。這是一個好習慣,否則在大型程序中會導致內存泄漏。

1

*是變量的類型的一部分,而不是它的名稱

int* j意思是「我有一個名爲j的變量,它是一個指向int的變量」。 (代碼2)的意思是「我有一個名爲j的變量,它是一個指向int的指針,它應該使用值50進行初始化」。這是不允許的;如果沒有明確的轉換,指針可能不會使用0以外的整數值進行初始化。 如果你不知道自己在做什麼,明確地施展以解決這個問題是一個非常非常糟糕的主意,如果你問這些問題,那麼這是絕對肯定的,你不知道你做得不夠好試試

你應該能夠從錯誤信息中弄清楚這一點。無效的轉換就是這樣:你的代碼試圖從一種類型轉換到另一種(通過賦值),這是無效的。您分配的內容與您分配的內容不兼容。它也會告訴你所涉及的類型是什麼。

*j = 50(代碼1中的第二行)表示「在j指向的位置寫入值50」。這是不好的,因爲j尚未初始化。 這被稱爲「未定義的行爲」,正是如此 - 它可能以任何方式失敗,或者不會,但即使它似乎正在工作,它總是錯誤的。但它會編譯,大多數編譯器甚至不會試圖警告你這類事情,除非你要求他們提供非常高的警告級別 - 如果有的話。

相關問題