日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

这几道 C/C 题涉及你的知识盲区?

發布時間:2023/12/2 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 这几道 C/C 题涉及你的知识盲区? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

8個C語言面試題,涉及指針、運算、函數、內存,看看你能做出幾個!

1.gets()函數

問:請找出下面代碼里的問題:

#include? int?main(void) {char?buff[10];memset(buff,?0,?sizeof(buff));gets(buff);?//gets不檢查輸入的字符串大小,可能造成緩存溢出printf("\n?The?buffer?entered?is?[%s]\n",?buff);return?0; }

答:上面代碼里的問題在于函數?gets()?的使用,這個函數從?stdin?接收一個字符串而不檢查它所復制的緩存的容積,這可能會導致緩存溢出。這里推薦使用標準函數?fgets()?代替。

2.strcpy()函數

問:下面是一個簡單的密碼保護功能,你能在不知道密碼的情況下將其破解嗎?

#include? #include int?main(int?argc,?char?*argv[])? {?int?flag?=?0;?char?passwd[10];?memset(passwd,0,sizeof(passwd));?strcpy(passwd,?argv[1]);?if(0?==?strcmp("LinuxGeek",?passwd))?{?flag?=?1;?}?if(flag)?{?printf("Password?cracked?\n");?}?else?{?printf("Incorrect?passwd?\n");?}?return?0;? }

答:破解上述加密的關鍵在于利用攻破?strcpy()?函數的漏洞。所以用戶在向?“passwd”?緩存輸入隨機密碼的時候并沒有提前檢查?“passwd”?的容量是否足夠。所以,如果用戶輸入一個足夠造成緩存溢出并且重寫?“flag”?變量默認值所存在位置的內存的長 “密碼” ,即使這個密碼無法通過驗證,?flag?驗證位也變成了非零,也就可以獲得被保護的數據了。例如:

ubuntu@VM-16-5-ubuntu:~$?g ?-o?test?test.c ubuntu@VM-16-5-ubuntu:~$?./test?aaaaaaaaaa Incorrect?passwd

雖然上面的密碼并不正確,但我們仍然可以通過?緩存溢出?繞開密碼安全保護。

要避免這樣的問題,建議使用?strncpy()?函數。

3.內存泄露

問:下面的代碼會導致內存泄漏嗎?

#include?void?main(void)? {?char?*ptr?=?(char*)malloc(10);?if(NULL?==?ptr)?{?printf("\n?Malloc?failed?\n");?return;?}?else?{?//?Do?some?processing?}?return;? }

答:盡管上面的代碼并沒有釋放分配給?“ptr”?的內存,但并不會在程序退出后導致內存泄漏。在程序結束后,所有這個程序分配的內存都會自動被處理掉。但如果上面的代碼處于一個?“while循環”?中,那將會導致嚴重的內存泄漏問題!

4.free()函數

問:下面的程序會在用戶輸入?’freeze’?的時候出問題,而?’zebra’?則不會,為什么?

#include? #include #include int?main(int?argc,?char?*argv[])? {?char?*ptr?=?(char*)malloc(10);?if(NULL?==?ptr)?{?printf("\n?Malloc?failed?\n");?return?-1;?}?else?if(argc?==?1)?{?printf("\n?Usage??\n");?}?else?{?memset(ptr,?0,?10);?strncpy(ptr,?argv[1],?9);?while(*ptr?!=?'z')?{?if(*ptr?==?'\0')?break;?else?ptr ;?}?if(*ptr?==?'z')?{?printf("\n?String?contains?'z'\n");?//?Do?some?more?processing?}?free(ptr);?}?return?0;? }

答:這里的問題在于,代碼會(通過增加?“ptr”?)修改while循環里?“ptr”?存儲的地址。當輸入?“zebra”?時,while?循環會在執行前被終止,因此傳給?free()?的變量就是傳給?malloc()?的地址。但在?“freeze”?時,“ptr”?存儲的地址會在?while?循環里被修改,因此導致傳給?free()?的地址出錯,也就導致了?seg-fault?或者崩潰。

5.使用_exit退出

問:在下面的代碼中,atexit()?并沒有被調用,為什么?

#include?? #include? #include? void?func(void)? {?printf("\n?Cleanup?function?called?\n");?return;? }? int?main(void)? {?int?i?=?0;?atexit(func);?for(;i<0xffffff;i );?_exit(0);? }

這是因為?_exit()?函數的使用,該函數并沒有調用?atexit()?等函數清理。如果使用?atexit()?就應當使用?exit()?或者?“return”?與之相配合。

6.問:修改代碼片段(或者只讀代碼)

問:下面的代碼段有錯,你能指出來嗎?

#include?int?main(void)? {?char?*ptr?=?"Linux";?*ptr?=?'T';?printf("\n?[%s]?\n",?ptr);?return?0;? }

答:這是因為,通過?*ptr = ‘T’,會改變內存中代碼段(只讀代碼)“Linux”?的第一個字母。這個操作是無效的,因此會造成?seg-fault?或者崩潰。

7.返回本地變量的地址

問:下面代碼有問題嗎?如果有,該怎么修改?

#include? int*?inc(int?val)? {?int?a?=?val;?a ;?return?&a;? }?int?main(void)? {?int?a?=?10;?int?*val?=?inc(a);?printf("\n?Incremented?value?is?equal?to?[%d]?\n",?*val);?return?0;? }

答:盡管上面的程序有時候能夠正常運行,但是在?“inc()”?中存在嚴重的漏洞。這個函數返回本地變量的地址。因為本地變量的生命周期就是?“inc()”?的生命周期,所以在?inc?結束后,使用本地變量會發生不好的結果。這可以通過將?main()?中變量?“a”?的地址來避免,這樣以后還可以修改這個地址存儲的值。

8.處理printf()的參數

問:下面代碼會輸出什么?

#include?int?main(void)? {?int?a?=?10,?b?=?20,?c?=?30;?printf("?%d..%d..%d?\n",?a b c,?(b?=?b*2),?(c?=?c*2));?return?0;? }

答:輸出結果是:

110..40..60

這是因為C語言里函數的參數默認是從右往左處理的,輸出時是從左往右。

聲明:

本文于網絡整理,版權歸原作者所有,如來源信息有誤或侵犯權益,請聯系我們刪除或授權事宜。

總結

以上是生活随笔為你收集整理的这几道 C/C 题涉及你的知识盲区?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。