国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
一道C語言安全編碼題目

1、前言

最近在網(wǎng)上看到一道C語言題目,用C語言實現(xiàn)一個函數(shù),給定一個int類型的整數(shù),函數(shù)輸出逆序的整數(shù),例如輸入123,則輸出字符串'321',,輸入-123,則輸出字符串'-321'。題目要求,不使用標準庫,不得分配內(nèi)存。當時覺得蠻簡單的,這不就是類似字符串逆轉嘛,自己嘗試做了一下,測試發(fā)現(xiàn),還是有很多地方考慮不周全。今天在此整理一下基礎知識,作為一名安全開發(fā)人員,時刻需要注意代碼的安全,防止有任何漏洞。題目給出的函數(shù)如下:

#include const char * parseInt(int data){ return '321';}int main{ printf('%s\n', parseInt(123)); return 0;}

2、思考過程

寫代碼最怕的就是沒有想好,一上來就寫,在寫的過程中不斷的測試修改,這樣很浪費時間。因此需要先好好想一下,這個題目到底考些什么呢?

(1)int類型的整數(shù)分為正數(shù)、0、負數(shù),如何處理這些邊界值

(2)整數(shù)與字符串之間的轉換,如何將一個整數(shù)轉換為一個字符

(3)如何返回一個const char * 類型的字符串

(4)當輸入的整數(shù)超過int的范圍如何處理

3、編碼過程

開始寫代碼的思路如下:定義一個char類型的數(shù)組,用于保存結果。使用對10取余和除法操作依次獲取每一位的數(shù)字,然后根據(jù)ASSIC碼轉換為字符。將字符拼接起來,返回字符串數(shù)組結果。編碼實現(xiàn)如下:

const char * parseInt(int data){ char str[16] = {0}; int i = 0; if (data < 0)="" {="" data="-data;" str[i++]='-' ;="" }="" int="" tmp="data;" while="" (tmp="" 10)="" {="" char="" ch="tmp" %="" 10="" +="" 48;="" tmp="tmp" 10;="" str[i++]="ch;" }="" str[i++]="tmp" %="" 10="" +="" 48;return="">

當初沒有考慮那么多,編譯發(fā)現(xiàn)出現(xiàn)如下錯誤:

一看編譯錯誤,才意識到自己掉入坑中。題目要求返回一個字符串,而且不用分配內(nèi)存。當時就想直接定義一個字符數(shù)組進行返回,而定義的str屬于函數(shù)局部變量。

一個函數(shù)的局部變量都是存在stack中的,當這個函數(shù)調(diào)用過程結束時,這個局部變量都是要釋放掉的,所以就會產(chǎn)生這樣的warning,這個是和變量的life time相關的,所以解決方法有:

1.將char result[16]改為static型

2.使用malloc向heap申請,這些是需要caller用free去釋放的

于是使用static 類型字符串,代碼改進如下:

1 const char * parseInt(int data) 2 { 3 static char str[16] = {0}; 4 int i = 0; 5 6 if (data < 0)="" {="" 7="" data="-data;" 8="" str[i++]='-' ;="" 9="" }="" 10="" 11="" int="" tmp="data;12" while="" (tmp="" 10="" !="0)" {13="" char="" ch="tmp" %="" 10="" +="" 48;="" 14="" tmp="tmp" 10;="" 15="" str[i++]="ch;" 16="" }="" 18="" str[i++]="tmp" %="" 10="" +="" 48;="" 20="" return="" str;21="">

int main

{

printf('%s\n', parseInt(123));

printf('%s\n', parseInt(12345678));

printf('%s\n', parseInt(-89790));

return 0;

}

測試結果如下:

改為static之后,編譯成功,看輸出的結果上看,前面兩個輸出是正確的,而第三個輸出的結果是錯誤的。尼瑪,再次掉入坑中,對static變量的應用不精通啊。為什么每次到看到結果后才想起來?

雖然在函數(shù)中定義了static局部變量,使得變量的變?yōu)殪o態(tài)stack存儲區(qū)域,生命周期從函數(shù)中變成了這個程序的范圍。但是static局部變量在函數(shù)第一次調(diào)用的時候會初始化,后面調(diào)用就不會了,直接使用了。因此導致了剛才的結果輸出不對,復用了上次遺留的結果。

static靜態(tài)局部變量屬于靜態(tài)存儲方式,它具有以下特點:

(1)靜態(tài)局部變量在函數(shù)內(nèi)定義 它的生存期為整個源程序,但是其作用域仍與自動變量相同,只能在定義該變量的函數(shù)內(nèi)使用該變量。退出該函數(shù)后, 盡管該變量還繼續(xù)存在,但不能使用它。

(2)允許對構造類靜態(tài)局部量賦初值 例如數(shù)組,若未賦以初值,則由系統(tǒng)自動賦以0值。

(3)對基本類型的靜態(tài)局部變量若在說明時未賦以初值,則系統(tǒng)自動賦予0值。而對自動變量不賦初值,則其值是不定的。 根據(jù)靜態(tài)局部變量的特點, 可以 看出它是一種生存期為整個源程序的量。雖然離開定義它的函數(shù)后不能使用,但如再次調(diào)用定義它的函數(shù)時,它又可繼續(xù)使用, 而且保存了前次被調(diào)用后留下的 值。 因此,當多次調(diào)用一個函數(shù)且要求在調(diào)用之間保留某些變量的值時,可考慮采用靜態(tài)局部變量。雖然用全局變量也可以達到上述目的,但全局變量有時會造成 意外的副作用,因此仍以采用局部靜態(tài)變量為宜。

第一次調(diào)用函數(shù),static變量,初始化。 第二次,及以后,調(diào)用函數(shù),static變量,不會初始化。

繼續(xù)改進代碼,在函數(shù)中將static變量每次使用for循環(huán)進行初始化,改進代碼如下:

1 #include 2 3 const char * parseInt(int data) 4 { 5 static char str[16] = {0}; 6 int i = 0; 7 8 int t = 0; 9 for (; t < 16;="" t++)="" {10="" str[t]="0;11" }12="" 13="" if="" (data="">< 0)="" {14="" data="-data;15" str[i++]='-' ;16="" }17="" 18="" int="" tmp="data;19" while="" (tmp="" 10="" !="0)" {20="" char="" ch="tmp" %="" 10="" +="" 48;21="" tmp="tmp" 10;22="" str[i++]="ch;23" }24="" 25="" str[i++]="tmp" %="" 10="" +="" 48;26="" 27="" return="" str;28="" }29="" 30="" int="" main31="" {32="" printf('%s\n',="" parseint(123));33="" printf('%s\n',="" parseint(12345678));34="" printf('%s\n',="" parseint(-89790));35="" return="" 0;36="">

這次輸出結果如下:

終于得到了正確答案,看似很簡單的題目,折騰的這么久,才搞出來。擴展一下,大家看看如下這個輸出什么呢:

printf('%s, %s, %s\n', parseInt(98989),parseInt(-4567), parseInt(123456));

這個結果是什么呢?為什么會這樣呢?

printf('%s\n', parseInt(0x8FFFFFFF));
printf('%s\n', parseInt(0xFFFFFFFF));

這個結果是什么呢?為什么會這樣呢?

int 類型4個字節(jié),32位組成。int的最高位作為符號位,需要特殊處理。

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
精心整理的C語言面試題目
C語言的那些秘密之---函數(shù)返回局部變量
西工大21年4月機考隨機《C語言程序設計》標準資料
C語言程序里全局變量、局部變量、堆、棧的存儲區(qū)域
關于函數(shù)返回局部指針的總結(大部分來自網(wǎng)文)
函數(shù)的返回類型為指針類型時的若干思考(字符串常量問題)
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服