線上系統發生了crash,后發現是整型溢出。
1、初始化函數的偽代碼:
init_mem(int count, int size){for(int i=0; i<count; i++)mem_list[i] = i*size; # 溢出發生的地方}
2、問題分析:
原有的變量?i、size?為有符號的int類型,int大小為4字節,int表示的最大正數為?0x7FFFFFFF。當?i?*?size?的乘積超過int表示的最大正數時,發生溢出。
char*?本質是一個無符號數,長度為8字節,char*?與?int相加時,int會自動轉換為無符號的8字節數值。當?int?溢出時,轉換出的無符號數與實際的數值不符,導致 men_list[i]?中保存的是一個無效地址,當訪問這個無效地址時,發生crash。
例如:i=47674881?時,?i*size?得值為,?十六進制0x88662030,十進制?-2006573008,已經溢出。其最高位為?1?表示負數。當與char*?相加時,由4位擴展到8位時,高位補符號位1,得到的值為?0xFFFFFFFF0x88662030,再與char*?相加,結果是一個非法地址。
當從mem_list[i]中取出非法地址進行訪問時,crash。
3、解決:
將 int 變量改為 無符號長整型size_t 或 unsigned long,防止溢出。