【陷阱代碼】c++ 第一篇 簡單但卻常見

主要來源是自己多年工程經驗以及審查代碼的總結,一些和常見的網上資料原理相同,但是實際場景經常比看起來複雜,一個疏忽就中了。

以下這個代碼,都不是基於冷門語法刻意考查基本功的,真正解決起來要靠警覺,就好比熟練的司機更容易出車禍一樣。


bool less(char* s1, char* s2)
{
	reutrn s1 == s2;                            //不要小看這個問題,看都看見,但是寫個模板,看不到類型時,容易疏忽
}

void percent(float cur, float base)
{
	if(base == 0)
		printf("error\n");
	else
		printf("%.2f", cur * 100 / base);    //溢出風險很大,先除後乘
}

struct node
{
	int data;
	struct node2 d2;
};
struct node2
{
	int data;
	struct node d1;   //循環引用初級問題,看題都可以答對,但面對大型工程,大量頭文件,特別大的結構體,查起來麻煩的很,要養成經常用指針的習慣
};

typedef struct node_s
{
	...
	struct node_s* next;
} node_t;

void free_list(node_t& head)				//head是哨兵,記了設置head.next = null
{
	for(node_t* ptr = head.next; ptr; ptr = ptr->next)
		free(ptr);
}

#define NewLine printf(“\n”);                    //宏分號導致下文的else語法錯誤,而且查起來麻煩。規範操作是不能加;
int rst = Deal();
if(rst == 1)                                       //這裏也可以規範化一下統一加{},但這會讓代碼變長,自由取捨,如果不加,建議備註下宏改變可能導致錯誤
	NewLine;
else
	printf(“line continue”);

typedef  map<int, int> IntMap;
IntMap::iterator itr = m_data.find(K);
itr->first = K2;                     //關聯容器是有序的(c++11提供了無序的unordered_map),這樣破壞了結構,正確做法移除再添加進去

typedef map<int, int> IntMap;
IntMap::iterator itr;
for(itr = m_data.begin(); itr != m_data.end(); itr++)
{
	if(itr->second <v)
		m_data.erase(itr);    //關聯容器刪除之後自增失效
}
正確寫法
typedef map IntMap;
IntMap::iterator itr;
for(itr = m_data.begin(); itr != m_data.end();)
{
	if(itr->second <v)
		m_data.erase(itr++);
        else
		itr++;
}


unsigned int i = 9;  //這個經常被人意識到
size_t i = 9;        //size_t是無符號的,而且是stl的標準大小類型,這個常有人犯
while(i>=0)  //無符號減不出負值  
{
	//do something
	i--;
}

string str = “hello”;
printf(“%s\n”, str);                //看題都容易找出來,但實際工作中,尤其是模板等,還是容易遇到的,標準做法是將格式化統一到一處函數內
cout << str << endl;


int i;
for(i = 0; i < 10; i++)
{
	if(str[i] == ‘\0’)
		break;
}
if(str[i] == ‘\0’)                  //是初級問題沒錯,但是溢出經常還是有效的內存並且是0,邏輯測試通過
	printf(“yes”);              //藉助工具倒是容易查出來但如果是自定義內存管理,經常要頭疼的去查問題了
else
	printf(“no”);



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章