一、發現問題
有三個小程式:
(1)用兩個指標變數指向字串
#include <iostream>using namespace std;#include <stdio.h>#include <string.h> int main(){ char *p = "welcome "; char *q = "to the house"; strcat(p, q); cout<<p<<endl; return 0;}
調試運行,會出現中斷,中斷位置在strcat.asm檔案中的main_loop處:
同時,彈出一個中斷資訊對話方塊:
(2)第一個用未指定大小的字元數組儲存字串,第二個用指標變數指向字串
#include <iostream>using namespace std;#include <stdio.h>#include <string.h> int main(){ char p[] = "welcome "; char *q = "to the house"; strcat(p, q); cout<<p<<endl; return 0;}
調試運行,會出現中斷,中斷位置在主函數的最後處:
同時,彈出一個中斷資訊對話方塊:
(3)第一個用指定大小的字元數組儲存字串,第二個用指標變數指向字串
#include <iostream>using namespace std;#include <stdio.h>#include <string.h> int main(){ char p[50] = "welcome "; char *q = "to the house"; strcat(p, q); cout<<p<<endl; system("PAUSE"); return 0;}
調試運行,沒有錯誤,運行結果如下:
二、分析問題
仔細查看這三個小程式,你會發現它們都是為了完成同一個功能:將字串"welcome "和"to the house"串連起來,它們實現的不同之處在於字串"welcome"的儲存方式。第一個和第二個程式調試運行都出現中斷,而第三個運行正常。這是為什麼呢?我終於弄明白了。
首先,要徹底理解strcat()函數。
其原型為 char *strcat(char *a, const char *b);
其作用為去掉字串a的結束符"\0"後,將字串b串連到a的後面,並儲存到a中。
因為strcat()是將a和b串連起來後存到a中,那麼a就要有足夠的儲存空間,否則就會溢出。
第一個程式中,採用的指標變數p儲存第一個字串。運行過程中,指標變數p所指向的記憶體是分配在堆中的,且只分配了足夠其指向的內容的記憶體。將q串連到p後,自然p是沒有其他空間給q了,所以出現了記憶體寫入衝突而中斷。
第二個程式中,採用未指定大小的數組p儲存第一個字串。運行過程中,數組p存放在棧中,因其未指定大小,那麼在初始化時,系統就預設其指定大小為初始化字串的長度。將q串連到p後,p也沒有多餘的空間給q,所以就出現了上述圖中的錯誤。
而第三個程式中,為數組p預先分配了50,其有足夠多餘的空間容納下q,所以運行無錯誤。