題1.關於ASSERT:
題目描述
void func() { char b[2]={0}; strcpy(b,"aaaa"); }
以下說法那個正確()
A. Debug版崩潰,Release版正常
B. Debug版正常,Release版崩潰
C. Debug版崩潰,Release版崩潰
D. Debug版正常,Release版正常
題庫答案:A
牛客網解析:
assert 含義是斷言,它是標準C++的cassert頭文件中定義的一個宏,用來判斷一個條件表達式的值是否爲ture,如果不爲true, 程序會終止,並且報告出錯誤,這樣就很容易將錯誤定位
通常我們開發的程序有2種模式:Debug模式和Release模式
- 在Debug模式下,編譯器會記錄很多調試信息,也可以加入很多測試代碼,比如加入斷言assert, 方便我們程序員測試,以及出現bug時的分析解決
- Release模式下,就沒有上述那些調試信息,而且編譯器也會自動優化一些代碼,這樣生成的程序性能是最優的,但是如果出現問題,就不方便分析測試了
因爲在Debug中有ASSERT斷言保護,所以要崩潰,而在Release優化中就會刪掉ASSERT,所以會出現正常運行。
但是不推薦如此做,因爲這樣會覆蓋不屬於自己的內存,這是搭上了程序崩潰的列車,即未定義行爲,出現什麼後果都有可能的,程序員的職責是保證不越界,而不是追問越界之後會發生什麼。就像生活中違法不一定立刻被抓,但是遲早是要被抓的。
動手測試:
環境:Visual Studio 2017
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void func()
{
char b[2] = { 0 };
strcpy(b, "aaaa");
}
int main()
{
func();
system("pause");
return 0;
}
測試結果:
-
debug版本
-
使用release版本:
先將運行庫從MDd變成MD,配置從debug改成release,然後運行代碼:
現象:release版本沒有報錯,不過窗口顯示幾秒鐘後自動退出了!!!
-
使用了gcc 7.4.0編譯器後
分別測試開調試和開優化,運行的時候:開調試會知道棧有出現問題,開優化直接知道溢出。編譯的時候都會提示操作越界,而且數值精確(感謝唐同學熱心解答!)
這道題的答案可能跟編譯器選擇有關係。在gcc 7.4.0中測試,兩種配置都會報錯。
題2. 編譯內存:
題目描述
關於下面程序說法正確的是( )
class Item { private: char *desc; int storage; public: Item() { desc = new char[51]; } void setInfo(char *dsrc, int num) { strcpy(desc,dsrc); storage = num; } }; int main() { Item stock; stock.setInfo("pen",20); return 0; }
正確答案: A
你的答案: C (錯誤)
A. main函數定義了一個stock對象佔8個字節
B. storage和desc成員各佔4個字節
C. 存在內存泄漏的問題
D. 存在編譯錯誤