【面試】 C++ 面試題筆記(不定期更新)

題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模式

  1. 在Debug模式下,編譯器會記錄很多調試信息,也可以加入很多測試代碼,比如加入斷言assert, 方便我們程序員測試,以及出現bug時的分析解決
  2. 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;
}

測試結果:

  1. debug版本
    在這裏插入圖片描述
    在這裏插入圖片描述
    在這裏插入圖片描述

  2. 使用release版本:
    在這裏插入圖片描述
    先將運行庫從MDd變成MD,配置從debug改成release,然後運行代碼:
    在這裏插入圖片描述

    現象:release版本沒有報錯,不過窗口顯示幾秒鐘後自動退出了!!!

  3. 使用了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. 存在編譯錯誤

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