2011-07-04 58 views
0
int main() { 


    char **k; 
    char *s ="abc"; 
    char *b ="def";  

    k = &s; 
    k++; 
    k = &b; 
    cout<<*(k - 1)<<endl; // nothing but newline. Shouldn't I get "abc"? 
    //EDIT: corrected a typo should be *(k - 1) 
} 

我什麼也沒有,但從coutnewline。當我查看char *的行爲時,我得到的印象是,因爲我有第一個字符的地址,所以我可以像char *一樣使用char *,這是真的。但是,對於char **,這種行爲似乎完全不同,當我嘗試k ++時,它看起來不像數組。這是爲什麼?另一個小內存C++問題

當我試過(K + 1)=&b;我有一個錯誤,爲什麼我不能那樣做?

回答

3

k是一個指向char的指針,所以當你前進的時候,它不會像你期待的那樣走下去。相反,它現在指向char *,它位於所指向的那個旁邊。在你的情況下沒有,所以當你打印*(k - 1)的值時,你要引用一個隨機存儲器位置。

(K + 1) = &b; 

以上是錯誤,因爲您必須在賦值左側有一個l值,它不能是臨時表達式(r值)。

編輯: 下面是一個例子,希望比閱讀你所犯的錯誤更容易遵循。

int main() 
{ 
    char **k; 
    char *s[2] = {"abc", "qwerty"}; 

    k = &s[0]; 
    std::cout << *(k + 1) << std::endl; // prints "qwerty" 

    k++; 
    std::cout << *(k - 1) << std::endl; // prints "abc" 

    std::cin.get(); 

    return 0; 
} 
+0

「現在它指向位於它所指向的char *旁邊的char *。」既然我用k ++先進k,不應該(k-1)是k? – Mark

+1

它會是,除了你在這之間做了這個任務:'k =&b;'。現在k指向b的地址,所以當你執行'k-1'時,它指向位於b之前的'char *'(沒有一個),所以當你打印它時會得到垃圾(或者它會讓你的程序崩潰)。 – Praetorian

+0

解釋了一切,謝謝你的回答 – Mark

2

由於您沒有將其指向數組,因此*(k-1)實際上正在訪問不確定的內存併產生未定義的行爲。

0

我將在代碼中添加一些示例值。請注意,我只是爲了說明而製作它們!我將假設一個32位(4字節)的指針。

char **k;  /* pointer @ 0x1000 */ 
char *s = "abc"; /* four bytes @ 0x2004 = "abc", pointer @ 0x1020 = 0x2004 */ 
char *b = "def"; /* four bytes @ 0x2000 = "def", pointer @ 0x1010 = 0x2000 */ 

k = &s; /* pointer @ 0x1000 now = 0x1020 */ 
k++;  /* pointer @ 0x1000 now = 0x1024 (one char* [4 bytes] more) */ 
k = &b; /* pointer @ 0x1000 now = 0x1010 */ 
cout<<*(k - 1)<<endl; /* k-1 = 0x100C ... *(k-1) = ??? */ 

EDIT在k = &...固定起來的錯誤,添加顯式32位指針大小。

+0

你在'0x1000'有兩個變量,'k-1'不是0x1FFF,它是'&b' - sizeof(char *)'。所有其他線路也完全錯誤。 'k =&s'使用's'的地址,而不是's'指向的地址,同上'k =&b'。 'k ++'增加了'sizeof(char *)'。 –

+0

@你說得對,對不起,我衝了k =&foo位。我可能不應該使用8位指針。編輯。 –

+0

雖然'k-1'將會是'0x100C',但這樣好多了。 –