2011-03-17 88 views
3

使用的ARM,C編譯器,我可以成功編譯和運行以下命令:Ç空指針與字符串文字

static char * myString = 0; 

void myfunc(int x){ 

    if (x <= 0) 
     myString = "Hello World"; 
    else 
     myString = "This is a different string with a different length"; 

} 

int main(){ 

    myfunc(-1); 
    printf("%s\n", myString); 
    myfunc(2); 
    printf("%s\n", myString); 
} 

爲什麼這項工作?

該指針不應該是一個NULL指針嗎?

至少,不應該將字符串文字分配在只讀內存位置?

編輯:它是一個C++編譯器

EDIT2:爲什麼字符串常量靜態範圍存在,MYFUNC已超出範圍後?字符串文字是否未在堆棧中聲明?何時它們被釋放?

謝謝!

+1

你能澄清你的問題嗎? 「myString」不再爲NULL的原因是您已分配給它。 – 2011-03-17 17:04:49

+0

請參閱EDIT2。感謝大家。 – 2011-03-17 17:06:48

+0

文字可能分配在只讀存儲器中。第一個的形式類型是'const char [12]'。你可以將它的地址分配給一個'char *',因爲它只允許在C中使用。爲了正確,你應該使用'const char *'。 – 2011-03-17 17:12:10

回答

7

這兩個字符串被分配在只讀存儲器中,並且完全不同。但是你用同一個指針來指向它們中的每一個......有什麼不明白的?

請記住,char*只是一個指針。它是可變的(非const)。

char* p = 0; 
p = "Hello"; //OK 
p = "Jo" //OK; 
p[0] = 'X' //OOPS, now THIS is bad (undefined behavior) 

您的編輯後:

沒有,字符串具有靜態存儲時間(不像其他所有文字),他們不是在堆棧中創建。它們將存在直到程序終止。

+0

請參閱有問題的edit2。謝謝阿門。 – 2011-03-17 17:08:36

+0

@J T:查看我的編輯 – 2011-03-17 17:09:58

+1

這裏存在未定義的行爲,因爲C兼容性損害了const的正確性。在虛構的類型安全世界中,將字符串文字分配給char *將是編譯時常量違例。 – 2011-03-17 17:24:16

1

這是,但是你分配一個指向字符串的指針,所以它指向兩個字符串數組中的一個。

0

最初它是一個空指針。但是你自己明確地改變了這個指針,並且在myfunc函數中使它變爲非null。

在第一次撥打myfunc時,您明確地將您的指針指向字符串字面值"Hello World"。在那一刻之後,指針當然不再爲空。

字符串文字確實分配在只讀內存位置(至少在概念上)。但是,在C和C++中,都允許您使用char *指針指向字符串文字(即不需要const char *)。只要指向就可以將字符串與char *指針串起來,只要你不試圖修改文字即可。你的代碼不會嘗試修改任何東西,所以它沒問題。

C和C++中的字符串文字具有靜態存儲持續時間。所以不,他們沒有被分配到「堆棧」上。它們總是被分配在靜態存儲器中,這意味着它們永遠活着 - 只要你的程序正在運行。

P.S.爲了更全面地回答你的問題,你必須解釋你爲什麼在地球上期望你的指針保持爲空。

P.P.S. int main,而不是void main

0

myString是一個指針變量,你故意將它設置爲指向存儲你的兩個字符串常量之一的內存。

3

如果你申報

char const *MyString = 0; 

那麼你會遇到麻煩的常量指針不能被重新分配。字符串文字是常量。

 .section  .rodata 
.LC0: 
     .string "Hello World" 
     .align 8 
.LC1: 
     .string "This is a different string with a different length" 
     .text 

字符串數據在只讀數據部分組裝。

2

通常在程序的「數據段」中創建常量字符串,並且指向它們的指針始終有效(字符串「objects」對程序生存期有效)。所以不行。字符串不會在堆棧上創建。

我相當肯定C中的語義是明確定義的。

快樂編碼。