2012-06-28 117 views
3

我的第一個問題在這裏。 我正在使用指針數組而不是二維數組。現在,要顯示一個元素,我可以使用*(arr [i] + j),其中arr是數組i表示列,j表示列。但是,當我嘗試爲使用相同記號的任何元素賦值時,代碼停止工作。我沒有收到編譯錯誤,但是當我運行它時,它只是停止工作。有人能幫助我嗎?使用指針陣列

這裏是我的代碼

#include <stdio.h> 
#include <conio.h> 
#include <string.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int i,j,k; 
    char temp2, temp, *arr[] = { 
     "Brinda Roy", 
     "Rakesh Bai", 
     "Neha Saxen", 
     "Ankit Jain"}; 

    printf("%c",*(arr[3]+8)); 

    for(i=0;i<4;i++){ 
     for(j=0, k=9; j<=4, k>=5; j++, k--){ 
      temp =*(arr[i]+j); 
      *(arr[i]+j)=*(arr[i]+k); 
      *(arr[i]+k)=temp; 
     } 

    } 

    printf("\nThe array is "); 

    for(i=0; i<4; i++){ 
     printf("\n%s",arr[i]); 
    } 

    getch(); 
    return 0; 
} 
+0

打開調試器,並在發生問題時檢查計數器的值。這可能是非常明顯的問題。 –

+2

指針數組只是一個2D數組。 'arr [i]'相當於'*(arr + i)'。 – Trevor

+0

您的錯誤可能是分段錯誤錯誤,這意味着數組在某處出界。它通常發生在玩指針時。嘗試調試您的代碼。 – ppsreejith

回答

2

您嘗試修改字符串文字。這是禁止的。請注意,即使這不是由類型系統強制執行(​​不是const char*),修改字符文字"abc"[1]='c'也會導致未定義的行爲。

您必須將您的數據移動到可寫位置。這樣做的最簡單的,但非標準的方法是使用strdup功能:

for(i=0; i<4; i++) 
    arr[i]=strdup(arr[i]); 

這將在堆中的字符串分配內存和字符串複製到它。如果您沒有strdup功能,則必須使用malloc,strlenmemcpy來實現它。

請注意,與動態分配的內存一樣,您必須釋放它;否則,你會得到內存泄漏。

順便說一句,訪問雙指針數組和多維數組的正常方法是arr[i][j]

+0

感謝您的幫助。我只是想練習指針數組,所以我試圖將所有二維數組代碼修改爲指針數組。我確實知道arr [i] [j]符號。不知道字符串文字。謝謝 – Swapnil

5

運行時崩潰是由於您修改了arr中的字符串文字。字符串文字"Brinda Roy","Rakesh Bai","Neha Saxen""Ankit Jain"應被視爲const char[],因爲它們可能存儲在程序的只讀部分。試圖改變它們的值導致未定義的行爲,如下面的評論中所述。

如果您想編輯這些只讀字符串,您需要將它們複製到非const緩衝區中。


如果你這樣做:

char *str = "message" 

你不應該修改數據通過str指出,因爲它指向只讀存儲器。


如果你這樣做:

char str[] = "message" 

可以修改數據通過str因爲只讀字符串字面"message"正在複製到數組str指向。


您的代碼屬於上面的第一種情況。

+2

Minor nit,字符串文字可能存儲在只讀部分。寫入它們是未定義的行爲,並且編譯器可以將它們放入可寫內存中。 – Michael

+0

@邁克爾:是的,這是一個更好的方式。 – AusCBloke

3

C允許通過此風格在源代碼中定義的字符串存儲在只讀數據部分。檢查此輸出:

$ cat storage.c 
int main(int argc, char* argv[]) { 
    char *arr[] = {"hello", "world"}; 
    arr[1][1]='a'; 
    return 0; 
} 
$ make storage 
cc  storage.c -o storage 
$ readelf -p.rodata storage 

String dump of section '.rodata': 
    [  4] hello 
    [  a] world 

我的編譯器字符串放入.rodata只讀數據段。當我嘗試了o更新到程序的a,程序死亡:

$ ./storage 
Segmentation fault (core dumped) 

這是一般適用於字符串定義爲以下任何代碼:

char *foo = "string"; 

如果你想創建在節目源的修改字符串,你會寫,而不是像這樣:

char foo[] = "string"; 

我不能肯定全部語法是什麼創建一個可修改的字符串數組;至少有以下醜陋方法工作,但我敢肯定有更好的東西:

char a1[] = "hello"; 
char a2[] = "world"; 
char *arr[] = {a1, a2}; 
+0

啊所以,而不是使用指針數組,如果我使用指向數組的指針,我將能夠修改字符串嗎? – Swapnil

+0

請注意,我的答案中的最後一行構建了指向char的指針數組 - 它不是指向數組的指針。 – sarnold

+0

噢。我明白你的意思。讓我試試看,回到你身邊。 編輯 - 它的工作。謝謝。但有沒有辦法不爲每個字符串聲明單獨的數組? – Swapnil

1

不能修改內存中保留這種方式:

{"Brinda Roy", 
"Rakesh Bai", 
"Neha Saxen", 
"Ankit Jain"}; 

當你定義一個char *這樣,它只是讀取內存。