2010-04-29 66 views
2

我已簡化了一直試圖隔離問題的問題,但它不起作用。c - 取消引用問題

我有一個2維char數組來表示內存。我想將一個對內存模擬的引用傳遞給一個函數。在測試內存內容的函數中,我只是想遍歷內存並打印出每一行的內容。

該程序打印出第一行,然後我得到seg故障。

我的程序如下:

#include <stdio.h> 

#include <stdlib.h> 

#include <ctype.h> 

#include <string.h> 

void test_memory(char*** memory_ref) { 

    int i; 
    for(i = 0; i < 3; i++) { 
     printf("%s\n", *memory_ref[i]); 
    } 
} 

int main() { 
    char** memory; 
    int i; 
    memory = calloc(sizeof(char*), 20); 
    for(i = 0; i < 20; i++) { 
     memory[i] = calloc(sizeof(char), 33); 
    } 

    memory[0] = "Mem 0"; 
    memory[1] = "Mem 1"; 
    memory[2] = "Mem 2"; 

    printf("memory[1] = %s\n", memory[1]); 

    test_memory(&memory); 

    return 0; 
} 

這使我的輸出:

memory[1] = Mem 1 
Mem 0 
Segmentation fault 

如果我改變了計劃,並通過取消引用memory_ref建立在功能的存儲器的本地版本,然後我得到正確的輸出:

因此:

#include <stdio.h> 

#include <stdlib.h> 

#include <ctype.h> 

#include <string.h> 

void test_memory(char*** memory_ref) { 

    char** memory = *memory_ref; 
    int i; 
    for(i = 0; i < 3; i++) { 
     printf("%s\n", memory[i]); 
    } 
} 

int main() { 
    char** memory; 
    int i; 
    memory = calloc(sizeof(char*), 20); 
    for(i = 0; i < 20; i++) { 
     memory[i] = calloc(sizeof(char), 33); 
    } 

    memory[0] = "Mem 0"; 
    memory[1] = "Mem 1"; 
    memory[2] = "Mem 2"; 

    printf("memory[1] = %s\n", memory[1]); 

    test_memory(&memory); 

    return 0; 
} 

給我下面的輸出:

memory[1] = Mem 1 
Mem 0 
Mem 1 
Mem 2 

這是我想要的,但使內存的本地版本,是無用的,因爲我需要能夠從功能改變原來的內存的值,其我只能通過解引用指向原始2d char數組的指針來完成。

我不明白爲什麼我會在第二輪遇到賽格錯誤,我會很感激任何建議。

非常感謝

回答

4

嘗試:

printf("%s\n", (*memory_ref)[i]); 

當前版本相當於

*(*(memory_ref + i)); 

這是因爲[]操作符比提領*更高的優先級。這意味着當i大於0您嘗試讀取內存後char***臨時memory_ref

第二個版本等於(*memory_ref)[i]這意味着你將索引正確的內存。

編輯:它適用於第一次迭代的原因是:

*(*(memory_ref + 0)) == *((*memory_ref) + 0) 
+0

這工作。非常感謝。我不知道爲什麼,但。 我猜想,括號允許提領操作試圖訪問提領操作的結果之前完成。 這仍然沒有按」牛逼是解釋在陣列打印的第一個字符串的行爲。我爲什麼沒有得到賽格故障第一次圓的? 非常感謝 喬 – Joe 2010-04-29 11:24:44

+0

看到我的編輯答案,'[]'比'*更高的優先級'。 – 2010-04-29 11:26:17

+0

@Joe至於爲什麼它第一次工作,請參閱我編輯的答案。 – 2010-04-29 11:28:23

2

這看起來像一個優先問題。首先評估[],然後評估*秒。你需要的是類似於你的第一個代碼示例的以下內容......

printf("%s\n", (*memory_ref)[i]); 
1

快速的解決辦法是使用

printf("%s\n", (*memory_ref)[i]); 

但我懷疑你有一個在線路的問題

memory[0] = "Mem 0"; 

這些不字符串「紀念品0」複製到你的記憶陣列。他們讓記憶[我]指向字符串。

您需要將數據用strncpy

例如明確複製 char s =「Mem 0」; strncpy(內存1,s,max(strlen(s)+ 1,29))//最大值30 =(29 char +'\ 0',因爲這是你分配的行長度 - 最好是#define this as a恆