在一次做題中溯祸,遇到的改錯(cuò)題甥厦,編譯是成功的栓霜,但是運(yùn)行會失敗寂殉。
實(shí)現(xiàn)hallo滓侍,world變成hello, world功能
為什么會掛掉镊尺?這個(gè)主要涉及到內(nèi)存分配問題烙样。在c/c++中开仰,一個(gè)程序編譯后占用的內(nèi)存分區(qū)如下:
1)常量區(qū):字符串常量存放的地方播赁。由系統(tǒng)在程序結(jié)束后釋放颂郎。
2)全局區(qū)(靜態(tài)區(qū)):存放全局變量以及靜態(tài)變量,初始化的全局變量和靜態(tài)變量在一塊區(qū)域容为,未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域乓序。由系統(tǒng)在程序結(jié)束后釋放。
3)堆區(qū):由程序員手動(dòng)分配和釋放舟奠,若程序員不釋放竭缝,程序結(jié)束可能由OS回收。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事沼瘫,分配方式倒是類似于鏈表抬纸。
4)棧區(qū):由編譯器自動(dòng)分配釋放? ,存放函數(shù)的參數(shù)值耿戚,局部變量的值等湿故。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。
5)程序代碼區(qū):存放函數(shù)體的二進(jìn)制代碼膜蛔。
舉個(gè)例子如下:
回到改錯(cuò)題坛猪,char *s = "hallo,world";應(yīng)該改成char s[] = "hallo,world";
首先得認(rèn)識到char *s = "hallo,world"中"hallo,world"是分配在文字常量區(qū)的,然后在棧上分配一個(gè)地址給s,并用s 指針指向這塊常量區(qū)域皂股。因此墅茉,當(dāng)通過指針修改常量區(qū)的時(shí)候就會崩潰。
char *s=''123'';char s[] = ''123'';這兩種的區(qū)別呜呐?
?[]是將123拷過去的放在棧上就斤,而指針的那種是直接就指向了那個(gè)常量; ?char *s和char s[]聲明的數(shù)組是均可以通過*(s+i)和s[i]來獲取的,但是進(jìn)行元素修改的話也只能通過[]這種聲明的蘑辑,那個(gè)指針的并不可以洋机。還有當(dāng)char s[]這種的數(shù)組作為函數(shù)參數(shù)的話,會退化成指針洋魂;還有sizeof []這種的是返回?cái)?shù)組里面存的內(nèi)存大小绷旗,若是sizeof 非[](即指針)會返回指針的大小喜鼓。只有char *s可以使用s++寫法,char s[]是不可以的衔肢,控制臺提示這個(gè)char[]類型的不可以增加庄岖。char s[]中,雖有s = &s[0]膀懈,但此時(shí)s是一個(gè)常數(shù)顿锰,&s[0]是無法改變的谨垃;但char *s作為指向s[0]的指針變量启搂,是可以任意改變的。故可用s++任意更改指針變量的值刘陶。
參考:
http://blog.chinaunix.net/uid-27002868-id-3275995.html
http://www.cnblogs.com/xxfighting/archive/2010/08/26/1809196.html
僅僅標(biāo)記一下胳赌,以供后續(xù)回憶。