收集整理的一些面試題

2021-06-09 23:10:54 字數 3705 閱讀 5221

1free()函式

問:下面的程式會在使用者輸入'freeze'的時候出問題,而'zebra'則不會,為什麼?

#include

int main(int argc, char *argv) 

else

if(argc == 1) 

else

if(*ptr == 'z') 

free(ptr); 

} return 0; 

}

答:這裡的問題在於,**會(通過增加「ptr」)修改while迴圈裡「ptr」儲存的位址。當輸入「zebra」時,while迴圈會在執行前被終止,因此傳給free()的變數就是傳給malloc()的位址,即最初分配給str的位址。但在「freeze」時,「ptr」儲存的位址會在while迴圈裡被修改,因此導致傳給free()的位址出錯,申請的記憶體前面一部分就沒有釋放,因為str++,讓釋放位址時不是從最初申請的那個位址開始釋放的,也就導致了seg-fault或者崩潰。

2.問:修改**片段(或者唯讀**)

問:下面的**段有錯,你能指出來嗎?

#include

int main(void) 

答:這是因為,通過*ptr = 『t』,會改變記憶體中**段(唯讀**)「linux」的第乙個字母。這個操作是無效的,因此會造成seg-fault或者崩潰。

試了一下,確實會出錯,但是還是不是很理解,為什麼像 *str++=*ptr++這種又是正確的了?

3、輸出是什麼結果,還有(int&)a   與   (int)&a   有什麼區別 

#include

using   namespace   std; 

void   main() 

解答:cout < < boolalpha < < ( (int)a == (int&)a ) < < endl; // 輸出0;

/*(int&)a:將a的引用強制轉換為整型,意思是a所在的記憶體,本來定義的時候為float型別,並初始為1.0f,但現在我要按int型別解釋這段記憶體。1.0f   在記憶體中的儲存為   0   011   1111   1   000   0000   0000   0000   0000   0000.把他按整型數解釋為2^29+2^28+2^27+2^26+2^25+2^24+2^23=1065353216       */ 

cout < < boolalpha < < ( (int)b == (int&)b ) < < endl; // 輸出1;

0.0   在記憶體中的的儲存形式 

0000   0000   0000   0000   0000   0000   0000   0000 

(int&)a   把a強制轉換成整形引用型別 ,

(int)&a   把a的位址強制轉換成整型 。

那為什麼(int)a=1呢,因為這個強制轉化不是轉化float在記憶體的儲存方式,而是轉化的a的值。

還要注意的是

用 #include

要加 using namespace std;

用iostream.h下面 ,就不用加 using namespace std;

國際標準化

#include

using namespace std;

不加.h的是現在c++中規定的標準,目的在於使c++**用於移植和混合嵌入時不受副檔名.h的限制,避免因為.h而造成的額外的處理和修改

而加.h的是c語言的用法,但是在c++中也支援這種用法,主要是為了向下相容c 的內容,我們平時盡量不用這種方法 iostream是現在c++中規定的標準,目的在於使c++**用於移植和混合嵌入時不受副檔名.h的限制,避免因為.h而造成的額外的處理和修改。iostream包含的基本功能和對應的舊標頭檔案相同,但標頭檔案的內容在名字空間std中。(在標準化的過程中,庫中有些部分的細節被修改了,所以舊標頭檔案和新標頭檔案中的實體不一定完全對應。) 一般情況下應該用這個標頭檔案,而iostream.h則是老式的,以後有可能被淘汰。  5、

下列**的執行結果是什麼?

int *ptr;

ptr=(int *)0x8000;

*ptr=3;

解答:指標問題,首先將指標ptr指向乙個指定的位址,即對乙個未作宣告的位址直接進行訪問,所以訪問出錯。這塊位址可能已經被用,或者被其他程式占用等,因此會導致錯誤。

int *ptr;

*ptr=3;

這樣也會導致錯誤,因為ptr沒有分配乙個合法的位址,在定義的時候,系統隨機分配了乙個位址給ptr,而這個位址可能是不合法的,已經被占用了的,所以會導致出錯,如果 int a;ptr=&a;加這兩句就不會出錯。

6、malloc與free是c++/c語言的標準庫函式,new/delete是c++的運算子。它們都可用於申請動態記憶體和釋放記憶體。

對於非內部資料型別的物件而言,光用maloc/free無法滿足動態物件的要求。物件在建立的同時要自動執行建構函式,物件在消亡之前要自動執行析構函式。由於malloc/free是庫函式而不是運算子,不在編譯器控制許可權之內,不能夠把執行建構函式和析構函式的任務強加於malloc/free。

因此c++語言需要乙個能完成動態記憶體分配和初始化工作的運算子new,以及乙個能完成清理與釋放記憶體工作的運算子delete。注意new/delete不是庫函式。

我們先看一看malloc/free和new/delete如何實現物件的動態記憶體管理,見示例7-8。

class obj

public :

obj(void)

~obj(void)

void    initialize(void)

void    destroy(void)

void usemallocfree(void)

obj  *a = (obj *)malloc(sizeof(obj));   // 申請動態記憶體

a->initialize();                        // 初始化

a->destroy();   // 清除工作

free(a);        // 釋放記憶體

void usenewdelete(void)

obj  *a = new obj;  // 申請動態記憶體並且初始化

delete a;           // 清除並且釋放記憶體

示例7-8 用malloc/free和new/delete如何實現物件的動態記憶體管理

類obj的函式initialize模擬了建構函式的功能,函式destroy模擬了析構函式的功能。函式usemallocfree中,由於malloc/free不能執行建構函式與析構函式,必須呼叫成員函式initialize和destroy來完成初始化與清除工作。函式usenewdelete則簡單得多。

所以我們不要企圖用malloc/free來完成動態物件的記憶體管理,應該用new/delete。由於內部資料型別的「物件」沒有構造與析構的過程,對它們而言malloc/free和new/delete是等價的。

既然new/delete的功能完全覆蓋了malloc/free,為什麼c++不把malloc/free淘汰出局呢?這是因為c++程式經常要呼叫c函式,而c程式只能用malloc/free管理動態記憶體。

如果用free釋放

「new建立的動態物件

」,那麼該物件因無法執行析構函式而可能導致程式出錯。如果用delete釋放

「malloc申請的動態記憶體

」,理論上講程式不會出錯,但是該程式的可讀性很差。所以new/delete必須配對使用,malloc/free也一樣。

一些面試題收集

1 const的實現機制 const修飾指標時,如果const位於 的左側,則const就是用來修飾指標所指向的變數,即指標指向乙個常量 如果const位於 的右側,const就是修飾指標本身,即指標本身是常量,指標不能改變。define巨集定義是在預處理階段直接展開的,不會有任何檢查機制。而con...

內網滲透一些命令收集整理

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!一些收集資訊的命令 查詢本機的一些情況 ipconfig all 查詢存在關係的機器 net view 查詢有幾個域 nei view damin 檢視 testdomain域中的計算機列表 net view domain testdomain 查...

一些常用的mysql命令收集整理

mysql命令列是學習mysql資料庫必須要掌握的知識,下面就為您介紹了10個好用的mysql命令列,希望對您學習mysql命令列方面能有所幫助。1 顯示資料表的結構 mysql describe 表名 desc 表名 2 建立資料表 mysql use 庫名 進入資料庫 mysql create ...