TAG

首都機能移轉 (2) 歌詞 (2) 靠北文 (40) 戲言 (30) 糟糕 (7) ACG (23) Assembly (2) Boost (2) C (31) C++ (69) CMake (4) CSIE (67) Debian (34) Design_Pattern (2) Django (1) Eclipse (1) en_US (13) FFmpeg (3) FoolproofProject (26) FreeBSD (2) Git (4) GNU_Linux (65) IDE (5) Java (11) JavaScript (19) KDE (15) Khopper (16) KomiX (3) Kubuntu (18) Life (1) Lighttpd (2) Mac_OS_X (2) Opera (1) PHP (2) PicKing (2) Programing (21) Prolog (1) Python (7) QSnapshot (2) Qt (30) Qt_Jambi (1) Regular_Expression (1) Shell_Script (7) Talk (98) VirtualBox (7) Visual_Studio (13) Windows (18) zh_TW (36)

2007年10月8日 星期一

C的字串寫入問題

一般說來,C字串的初始化有三種方法:
char * str1 = "All your base are belong to us.";
char str2[] = "All your base are belong to us.";
char str3[32] = "All your base are belong to us.";
是的,學過C的都知道。
但是,它們底下的意義有點不同;有人會說pointer和array在內部是類似的,可是我認為這是非常危險的想法。
我想先從第三個說回去好了。str3的初始化即為:宣告一個長度為32的字元陣列,並把字串常數放進去;由於字串長度為31,加上C字串的結尾字元,總共是32,沒有問題。str2的初始化則是交給編譯器自行決定一個容納字串的陣列,通常會是剛好能容納該字串的大小。但是str1呢?它的意思是,宣告一個字元指標指向某個字串;好吧,問題出在哪裡?
現在問題是,這個字串到底放在哪裡?你真的有宣告出一個空間來置放它嗎?這個字元指標指向的空間真的是一個你可以控制的實體嗎?
我想答案應該在你試圖更改這個字串的內容時就會出現了。
不管是字串常數或是用getenv之類的函式傳回的字串,你都沒有真正的寫入權。當你需要更動它們的值時,請愛用strcpy;否則你就會被Segmentation fault吃到死。
總之,在對指標作操作時,一定要搞清楚:這個指標指向的空間到底是什麼東西?搞不清楚的話你就會下地獄。
這也是為什麼我說指標是邪惡的東西。C的指標運用毫無安全性可言,它也沒有像C++或JAVA或其他近代高階語言一樣有exception handling,C++雖然還是有pointer和iterator,但是至少有exception來避免程式死亡,或是使用smart pointer來取代pointer,C的情況是爆了就是爆了,然後你要花三倍的時間去研究到底是哪裡存取錯誤。
因此有句話說得好:
你想要的,朕會給你;朕不給的,你不能搶!
by 滿城盡帶bra甲

2 則留言:

  1. 沒錯,說的好。能不用指標就不要用指標,不然到時候死的是自己.......

    回覆刪除
  2. 大推!!
    看到這一篇才知道我錯在哪= =~

    回覆刪除