C语言面试题分享(6)
注:以下都是找錯題(即:找出程序中的錯誤或不合理的地方)
一、
解答:字符串str1有11個字節(包括末尾的結束符’\0’),而數組string只有10個字節,故而使用strcpy函數將str1復制到string中會導致數組string越界一個字節,可能導致系統崩潰。
題外:
使用如下例程探究一下strcpy函數復制字符串時是否會把’\0’也一并復制過去。
結果:
可見strcpy函數復制字符串時會把’\0’也一并復制過去。
上面這個測試記錄一個小問題
一開始unsigned char str1[10] = {0};用的是char型的,導致%X輸出來每個元素是0xFFFFFFFF,與設想的0xFF不符,究其原因是%x要求的是無符號整形變量,而如果傳入的是char型,這里有一個整數提升的問題。char作為有符號數,提升到無符號整數,由于char的值為0xFF,那么提升時,前面的填充位為1。所以提升后其值為0xFFFFFFFF
解決辦法:
把char類型強制轉換為uint8_t(即unsigned char),使用uint8_t時,是無符號提升,前面的填充為0,所以提升后的值為0xFF
二、
void test2() {char string[10], str1[10];int i;for(i=0; i<10; i++){str1= 'a';}strcpy(string, str1); }解答:str1[10]是局部變量,沒有初始化可能元素都是隨機數,因此str1[]里可能沒有沒有結束符’\0’,strcpy函數是把含有’\0’結束符的字符串source(包含’\0’)復制到另一個地址空間destin。故而使用strcpy復制時很可能導致數組越界引起系統崩潰。
三、
void test3(char* str1) {char string[10];if(strlen(str1) <= 10 ){strcpy(string, str1);} }解答:應修改為if (strlen(str1) < 10),因為strlen的結果未統計最后的結束符’\0’,如果str1恰好是11個字節的字符串包含最后的’\0’,使用strcpy時會導致string寫入越界。
四、
void GetMemory(char *p) {p = (char *)malloc( 100 ); }void Test( void ) {char *str = NULL;GetMemory(str);strcpy(str,"hello world");printf(str); }解答:C語言中的函數參數為傳值參數,在函數內對形參的修改并不能改變對應實參的值。故而調用GetMemory后,str的值沒有改變,仍為NULL。這里完成功能要用二級指針。
另外一個錯誤,沒有釋放內存。
正確的應改為:
評析:
(1)目的:通過調用子函數,為主函數指針分配一塊內存空間;
在調用GetMemory時,實參值為&str,即指針str的地址;GetMemory執行時,分配臨時變量p=&str; p=(char)malloc(100)操作等同于:str=(char*)malloc(100);即通過調用子函數,為主函數指針分配一塊內存空間。
(2)注意:如果malloc函數被調用,則后續函數中一定需要有free將對應的內存釋放,否則可能導致內存泄露;當free§后,需要讓p=NULL,否則指針p會成為野指針!
五、
char *GetMemory( void ) {char p[] = "hello world";return p; } void Test( void ) {char *str = NULL;str = GetMemory();printf(str); }解答:GetMemory中,p數組為局部變量,在函數返回后,該數組空間被釋放。故而str指向被釋放的地址空間,可能打印亂碼。實測如下:
六、
解答:試題6避免了試題4的問題,但在GetMemory內,未對p為NULL情況的判斷。當p不為NULL時,在printf后,也未對malloc的空間進行free。
七、
void Test( void ) {char *str = (char *)malloc( 100 );strcpy(str, "hello" );free(str);... //省略的其它語句 }解答:未對str為NULL的情況的判斷,在free(str)后,str未設置為NULL,可能變成一個野指針(后面對str的操作可能會導致踩內存)。
八、
swap(int* p1,int* p2) {int *p;*p = *p1;*p1 = *p2;*p2 = *p; }解答:上述函數功能,p1和p2指向的int數進行值互換
在swap函數中,p是個野指針,*p操作將導致程序運行的崩潰。故而,程序應改為:
總結
以上是生活随笔為你收集整理的C语言面试题分享(6)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RT-Thread uart串口设备驱动
- 下一篇: Git入门教程详解