[問題] 此段程式哪裡有問題

作者: chiya1908 (leowu)   2024-03-08 16:44:54
開發平台(Platform): (Ex: Win10, Linux, ...)
windows
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
GCC
額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
NO
問題(Question):
此段程式有甚麼risks 跟 如何改進他
程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔)
void clean_buffer(int A[], unsigned int number){
unsigned int i;
if(number > 0){
for(i = 0; i <= number - 1; i++){
A[i] = 0;
}
}
}
這題是去年在NV面試時遇到的考題
考官有提到number 跟 array A[] 的size是一樣的
但答案是跟 overflow 或是 踩到未定義記憶體位址有關係
實在是忘記當初的答案 最近想到這題實在是太想知道答案
無奈chatgpt沒辦法給出正確的回答 上來請教各位大大 再麻煩幫忙解惑了
作者: nh60211as   2024-03-08 17:40:00
number - 1 遇到 number==0 會 overflow
作者: gusion   2024-03-08 17:48:00
code看起來好像沒問題,不過可以簡化,if判斷拿掉,for的條件改成i < number看起來比較乾淨
作者: firejox (Tangent)   2024-03-08 17:51:00
考題應該沒有if
作者: amamoimi (佛仔)   2024-03-08 17:52:00
number==0直接就不會進迴圈了吧
作者: chiya1908 (leowu)   2024-03-08 17:57:00
考題有if 這是我直接複製下來的我也記得他好像是說number的地方要改
作者: simon860730 (╰電磁學╮╭爆炸囉╯)   2024-03-08 18:06:00
for裡面的條件改成 i < number 應該連if都不用包了
作者: nh60211as   2024-03-08 19:33:00
int 比 uint 還是要轉型,那就有可能不是你預期的比較結果阿抱歉看錯
作者: KaryuuIssen (一閃)   2024-03-08 19:34:00
邏輯上沒什麼問題 難道他是希望你把number和i的型別換成size_t ?
作者: nh60211as   2024-03-08 20:00:00
實際跑了一下,好像 clean_buffer(int* A, unsigned比較像正常的寫法
作者: Richun (解放左手的OO之力)   2024-03-08 20:26:00
該不會是說int不一定對齊記憶體大小,要用unsigned long吧有可能就是K大講的那個,要size_t去對到CPU定址能力。
作者: stupid0319 (徵女友)   2024-03-08 21:11:00
可能要檢查 A != NULL 吧
作者: Dracarys (MayShowGunMore)   2024-03-08 22:21:00
答案應該是unsigned int有可能無法表達std::size_t所有的數,可以用T (&A)[N]https://godbolt.org/z/GMxdPcrYzint* A比較正常的說法聽起來怪怪的,因為本來就一樣https://eel.is/c++draft/dcl.fct#5.sentence-3
作者: wulouise (在線上!=在電腦前)   2024-03-08 22:48:00
沒說這題是考c還是c++啊
作者: peter98 (新兵)   2024-03-09 05:41:00
會不會是你記錯題目? 考題裡的i是不是int而不是你記得的unsigned int? 如果i的型別是int的話會有問題但我想想又有矛盾,如果是因為i的型別為int而造成的overflow,那那個number會很大,而這個number又是array size理論上應該沒這麼大的array才對。。。如果array是動態配置的可能可以,但如果array是動態配置function參數寫int []我會想砍人
作者: cylee (Artisan)   2024-03-09 11:06:00
是我的話會用 memset;不過搞不好是禁用?
作者: wulouise (在線上!=在電腦前)   2024-03-09 17:20:00
我覺得這題應該要問Caller
作者: shibin (喜餅)   2024-03-10 00:39:00
認同一樓說的,number==0會變無窮迴圈
作者: chuegou (chuegou)   2024-03-10 22:00:00
認同上面兩樓 問caller
作者: manmay (書誠)   2024-03-11 19:56:00
如果是說未定義記憶體位置有說陣列長度為多少嗎number-1的索引是否超過原本陣列的大小
作者: hongsiangfu   2024-03-12 09:03:00
number過大會造成A位址回卷,因為A不是對齊bit0(猜
作者: rnoro (隼)   2024-03-13 08:17:00
認同一樓,unsigned int的-1是-1的補數,通常非常非常大XD
作者: joefaq (小瑜)   2024-03-17 04:29:00
number == UINT_MAX 會變無窮迴圈
作者: wulouise (在線上!=在電腦前)   2024-03-17 19:20:00
外面有number>0,overflow的情況裡面不會出現吧
作者: Lipraxde (Lipraxde)   2024-03-17 20:23:00
你會不會其實不小心把答案跟題目弄反了?一般用 unsigned 可能寫成 for (unsigned i; i < n; ++i),沒意識到n 可能是 0?
作者: sanctitysky (常自在)   2024-03-18 02:50:00
會計算 n+1次 n-1 很浪費效能?還是char*?for buffer?
作者: ddavid (謊言接線生)   2024-03-18 12:39:00
number 為 0 就已經被 if(number > 0) 擋掉了,不會出事啊至於 number 過大,原Po已經說「考官有提到number 跟array A[] 的size是一樣的」,你要搞出一個 stack 宣告得出來但是 unsigned int 存不下的陣列大小?因為是 int 陣列,似乎需要 > 16GB 的 stack 大小呢XD在這之前,這個陣列要怎麼宣告出來XD
作者: shibin (喜餅)   2024-03-18 17:01:00
喔喔,那個if被我無視了,那應該不是這問題
作者: Fenikso (薪水小偷)   2024-03-20 22:28:00
為什麼一定要放stack XD
作者: adamkk (愛還記得嗎)   2024-04-03 23:15:00
看不出來,就算是alignment的問題,array的記憶體位置也會shift到對的位置。目前看得比較會是i <= number - 1的編譯順序會不會不一樣
作者: wulouise (在線上!=在電腦前)   2024-04-04 17:04:00
看起來最有可能的是caller給的size會超過uint吧,清不乾淨
作者: firejox (Tangent)   2024-04-05 08:40:00
我有點好奇是否有因為optimization 省略if的情況
作者: LPH66 (-6.2598534e+18f)   2024-04-05 23:57:00
最佳化的話可能要編譯器能 (1) 把迴圈化簡成 memset 之後(2) 這個函數被 inline (3) if 的條件在上層函數已滿足不過 (3) 這個條件記得不容易滿足 (技術上&實際程式上都是)
作者: firejox (Tangent)   2024-04-06 21:31:00
了解,仔細想caller給的size超過unsigned是有可能的,以c標準而言,unsigned是有可能16bit的。
作者: bizer (bizer)   2024-04-19 11:04:00
會不會是number給的size是byte,也就是 sizeof (unsigned int)計算byte,但你是用unsigned int去做index所以會爆掉?int A[i]會位移爆掉?
作者: adamkk (愛還記得嗎)   2024-05-18 23:44:00
會不會跟32bit記憶體定址有關?

Links booklink

Contact Us: admin [ a t ] ucptt.com