这道笔试题竟然运行不出错
#讀者提供的面試題
下面這張截圖是一個(gè)讀者在面試的時(shí)候遇到的題目,是哪個(gè)公司的我就不說(shuō)出來(lái)了,我在微信朋友圈發(fā)了這個(gè)題目后,有幾個(gè)好友給我留言說(shuō)自己也寫(xiě)了這道題。
題目:下面這段代碼有什么問(wèn)題?
#后續(xù)
然后我就用這個(gè)圖片發(fā)了朋友圈,很多人也回復(fù)了,天資跟我差不多的人呢,都看出來(lái)了就是 if 判斷的代碼需要往上移動(dòng)下,要不然呢,malloc 后沒(méi)有釋放,就會(huì)出現(xiàn)內(nèi)存泄漏。
這個(gè)是基本的,還有一些后續(xù)的回復(fù),有幾個(gè)微信好友回復(fù)還是比較不錯(cuò),在這里分享給大家。
#我寫(xiě)的測(cè)試源碼
#include?"stdio.h" #include?"stdlib.h" #include?"string.h"int?swap(void?*a,void*?b,int?size) {void?*p;p?=?malloc(size);if(size?<=?0){printf("error");return?-1;}memcpy(p,a,size);memcpy(a,b,size);memcpy(b,p,size);free(p);return?0; }?int?main() {char?*a?=?"12344";char?*b?=?"adbde";swap(a,b,5);printf("a:%s\tb:%s\n",a,b);return?0; }程序輸出
a:adbde?b:12344-------------------------------- Process?exited?after?0.03298?seconds?with?return?value?0 請(qǐng)按任意鍵繼續(xù).?.?.#void* 指針
程序里面有一個(gè) void 指針,這個(gè)需要注意下,void指針是可以接收所有類(lèi)型的指針的,但是其他類(lèi)型的指針是不能直接接收void指針的。
比如這樣
#include?"stdio.h"int?main() {?void?*p?=?NULL;char?*p1?=?NULL;p?=?p1;return?0; }下面這樣可能是有問(wèn)題的
我說(shuō)是可能有問(wèn)題是因?yàn)镚CC、ANSI C 的編譯情況是不同的。
#include?"stdio.h"int?main() {?void?*p?=?NULL;char?*p1?=?NULL;p1?=?p;return?0; }#程序有什么問(wèn)題?
這段代碼有以下幾點(diǎn)問(wèn)題:
1、入?yún)和b都是void類(lèi)型的指針,不清楚a和b指向buff的長(zhǎng)度是否都為size?size不要設(shè)置成int,最好設(shè)置成unsigned?int,?而且a和b入?yún)⒁欢ú荒艽隿onst?xxxxx?*類(lèi)型的實(shí)參;
2、?進(jìn)入函數(shù)體之后應(yīng)該首先判斷size是否小于等于0、a和b是否為NULL,如果size小于等于0,或者a和b存在NULL,那其他代碼將毫無(wú)意義。
3、沒(méi)有if(!p)對(duì)malloc進(jìn)行判斷直接使用p,剩余內(nèi)存較低情況下malloc一片大內(nèi)存是有可能fail的,直接使用p就會(huì)段錯(cuò),而且不建議malloc。
4、memcpy時(shí)因并不明確a?b指針指向buff的長(zhǎng)度是否都為size,存在內(nèi)存越界風(fēng)險(xiǎn)。
綜上述修改代碼為:
int?swap(void?*a,?void?*b,?uint32_t?len_a,?uint32_t?len_b) {if?(?!a?||?!b?||?!len_a?||?!len_b?||?len_a!=len_b?)?{printf("invalid?param!?\n");return?-1;}if?(?a==b?)?{printf("the?same!?\n");return?0;}uint32_t?len?=?len_a;char?*p?=?(char?*)malloc(len);if?(!p)?{printf("malloc?fail!?\n");return?-1;}memcpy(p,a,len);memcpy(a,b,len);memcpy(b,p,len);free(p);return?0; }#參考代碼
//我寫(xiě)了一個(gè)swap: //感謝讀者LinuxEnginetypedef?struct?{char?byte[4]; }?stdb_4; typedef?struct?{char?byte[8]; }?stdb_8;void?my_swap(void?*p,?void?*q,?size_t?p_sz,?size_t?q_sz) {char?buff[256];if?(?!p?||?!q?||!p_sz?||?!q_sz?||?p_sz?!=?q_sz?||?p==q?)return;int?sz?=?p_sz;if?(?sz?==?4?)?{stdb_4?t??=?*(stdb_4?*)p;*(stdb_4?*)p??=?*(stdb_4?*)q;*(stdb_4?*)q??=?t;return;}?else?if?(?sz?==?8?)?{stdb_8?t??=?*(stdb_8?*)p;*(stdb_8?*)p??=?*(stdb_8?*)q;*(stdb_8?*)q??=?t;return;}while?(?sz?>?sizeof(buff)?)?{my_swap?(p,?q,?sizeof(buff));p?=?(char?*)p?+?sizeof(buff);q?=?(char?*)q?+?sizeof(buff);sz?-=?sizeof(buff);}memcpy(buff,?p,????sz);memcpy(p,????q,????sz);memcpy(q,????buff,?sz); }#后續(xù)
感謝讀者LinuxEngine給出的答案以及示例代碼,大家如果看到有優(yōu)化的地方,可以在評(píng)論區(qū)說(shuō)出你的答案,寫(xiě)程序是一個(gè)非常嚴(yán)謹(jǐn)?shù)氖虑?#xff0c;程序?qū)懙脟?yán)謹(jǐn)了,該考慮到的問(wèn)題都能想到了,大概率就能去除一些比較明顯的bug。
祝大家周末愉快!
? #推薦閱讀:
? ??專(zhuān)輯|Linux文章匯總
? ??專(zhuān)輯|程序人生
? ??專(zhuān)輯|C語(yǔ)言
嵌入式Linux
微信掃描二維碼,關(guān)注我的公眾號(hào)?
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的这道笔试题竟然运行不出错的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 解读Android 4.0 Camera
- 下一篇: sql常用函数大全