2012-07-23 244 views
-4

我卡住了,無法弄清楚爲什麼這是下面的一段代碼沒有運行。我是相當新的c/c + +。爲什麼這會失敗

#include <iostream> 
int main(){ 
    const char *arr="Hello"; 
    const char * arr1="World"; 

    char **arr2=NULL; 
    arr2[0]=arr; 
    arr2[1]=arr1; 

    for (int i=0;i<=1;i++){ 
     std::cout<<arr2[i]<<std::endl; 
    } 
    return 0; 
} 

這裏,因爲這是運行完全正常

#include <iostream> 
int main(){ 

    const char *arr="Hello"; 
    const char * arr1="World"; 

    char *arr2[1]; 
    arr2[0]=arr; 
    arr2[1]=arr1; 

    for (int i=0;i<=1;i++){ 
     std::cout<<arr2[i]<<std::endl; 
    } 
    return 0; 
} 

這是爲什麼?並且一般如何迭代char **? 謝謝

+1

看來,你對指針的工作方式並沒有很好的掌握。從這些行中:'char ** arr2 = NULL;' 'arr2 [0] = arr;' 'arr2 [1] = arr1;' – OmnipotentEntity 2012-07-23 07:10:20

+0

在第二種情況下,它不能正常工作:變量在堆棧上。 – nhahtdh 2012-07-23 07:11:18

+0

如果您在C++中停止使用原始字符數組並使用字符串類,則所有問題都會消失。將'#include '添加到代碼文件的頂部,並用'std :: string'替換所有這些混亂。 – 2012-07-23 07:16:20

回答

3

char *arr2[1];是一個數組,其中一個元素(分配在堆棧上)類型爲「指向char的指針」。 arr2[0]是該數組中的第一個元素。 arr2[1]未定義。

char **arr2=NULL;是指向「指向char的指針」的指針。請注意,內存分配在堆棧上。 arr2[0]未定義。

底線,您的版本都不正確。第二個變種是「運行完美」只是提醒你多出來的代碼可以出現正常運行,直到疏忽編程真的咬你你以後,讓你浪費時間和日子在調試,因爲你拋棄了堆棧。

編輯:而且 「罪行」 中的代碼:

  1. 字符串文字char const *類型,難道你忘了const
  2. 縮進函數的代碼是很常見的(也是推薦的)。
  3. 這是(恕我直言)良好的做法,在各地增加空間,以提高可讀性(例如後(,前),前後二元運算符,後;for聲明等)。口味不同,有一個聲音派別,實際上鼓勵留出空間儘可能,但你並沒有做一致 - 和一致性 universially建議。嘗試代碼重新格式化,如astyle,看看他們可以做些什麼來提高可讀性。
+0

它們也不正確,因爲C++中的字符常量是'const'。任何體面的編譯器都應該發出警告。 – 2012-07-23 07:17:09

+0

@CodyGray:其實我看起來並沒有那麼遠,並且在答案中,甚至連提*這樣的東西(或者非縮進,非間距的可怕代碼風格)都太失望了。這就像對聾啞人講道一樣。 – DevSolar 2012-07-23 07:20:54

+0

正是我爲什麼停止寫一個答案,並+ 1'剛剛出現與重要的事情在黑體。 :-) – 2012-07-23 07:51:25

1

這是不正確的,因爲ARR2不指向任何東西:

char **arr2=NULL; 
arr2[0]=arr; 
arr2[1]=arr1; 

正確的方法:

char *arr2[2] = { NULL }; 
arr2[0]=arr; 
arr2[1]=arr1; 

這也是錯誤的,ARR2有大小1:

char *arr2[1]; 
arr2[0]=arr; 
arr2[1]=arr1; 

正確的方法是一樣的:

char *arr2[2] = { NULL }; 
arr2[0]=arr; 
arr2[1]=arr1; 
0

簡單地說,指針的聲明不會保留任何內存,而數組的declration不會。

在你的第一個例子中 你的行char ** arr2 = NULL聲明瞭一個指向字符指針的指針,但沒有將它設置爲任何值 - 因此它開始指向零字節(NULL == 0)。當你說arr2 [0] =你試圖將一個不屬於你的值置於零的位置時 - 這就是崩潰。

在你的第二個例子中: 聲明* arr2 [2]確實爲兩個指針保留空間,因此它工作。

+1

聲明不一定保留任何內存,但定義確實如此,並且他的所有聲明都是定義。問題在於,他所擁有的是指針的定義只會用指針類型創建一個對象。他用一個空指針進行初始化 - 儘管如此。他在第一種情況下的問題是他解除引用空指針。 – 2012-07-23 07:28:31

1
char **arr2=NULL; 

是一個指針,指向空而

char *arr2[1]; 

是已分配的空間的指針用於兩個項目的數組的指針。

在指針指針的第二種情況下,您正嘗試將數據寫入不存在的內存位置,而首先編譯器已經爲該數組分配了兩個內存槽,以便您可以分配值的兩個元素。

如果你認爲它非常簡單,C指針只是一個整型變量,其實際值是一個內存地址。所以通過定義char *x = NULL你實際上定義了一個整型變量,其值爲NULL(即零)。現在假設你寫了類似*x = 5;這意味着轉到存儲在x(NULL)內部的內存地址並在其中寫入5。由於沒有地址爲0的內存插槽,因此整個語句失敗。

說實話,自從我上次以來我一直在處理這些東西,但是在這裏可以用this little tutorial來處理,可能會清除C++中數組和指針的運動。