1free()函式
問:下面的程式會在使用者輸入'freeze'的時候出問題,而'zebra'則不會,為什麼?
#include答:這裡的問題在於,**會(通過增加「ptr」)修改while迴圈裡「ptr」儲存的位址。當輸入「zebra」時,while迴圈會在執行前被終止,因此傳給free()的變數就是傳給malloc()的位址,即最初分配給str的位址。但在「freeze」時,「ptr」儲存的位址會在while迴圈裡被修改,因此導致傳給free()的位址出錯,申請的記憶體前面一部分就沒有釋放,因為str++,讓釋放位址時不是從最初申請的那個位址開始釋放的,也就導致了seg-fault或者崩潰。int main(int argc, char *argv)
else
if(argc == 1)
else
if(*ptr == 'z')
free(ptr);
} return 0;
}
2.問:修改**片段(或者唯讀**)
問:下面的**段有錯,你能指出來嗎?
#include答:這是因為,通過*ptr = 『t』,會改變記憶體中**段(唯讀**)「linux」的第乙個字母。這個操作是無效的,因此會造成seg-fault或者崩潰。int main(void)
試了一下,確實會出錯,但是還是不是很理解,為什麼像 *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 ...