C語言中strcpy為什么不安全?如何解決?
主要原因是缺乏對輸入長度的邊界檢查,容易導致緩沖區溢出漏洞。
解決:可以使用strncpy函數替代,或者在程序最頂端加入代碼段
#define _CRT_SECURE_NO_WARNINGS
緩沖區溢出
緩沖區通常指的是用于存儲數據的連續內存塊。在輸入輸出操作中,緩沖區被用來臨時存儲數據,以便進行讀取或寫入操作。
緩沖區溢出(Buffer Overflow)是指當往一個緩沖區寫入超過其容量的數據時,導致數據溢出到其他內存區域,造成程序運行時的問題。這種情況通常發生在寫入數據時緩沖區的大小不足以容納所寫入的數據量。
緩沖區溢出可能會導致以下問題:
- 覆蓋數據:超出緩沖區邊界的數據可能會覆蓋其他數據,導致數據的丟失或損壞。
- 程序崩潰:緩沖區溢出可能引發程序崩潰或異常終止,因為溢出的數據可能會影響程序的控制流和運行狀態。
- 安全漏洞:惡意攻擊者可以利用緩沖區溢出漏洞執行惡意代碼,例如注入惡意指令或覆蓋函數返回地址。
C++容器不是線程安全的,怎么解決?
解決非線程安全容器(如map vector)的方法:同步
- 互斥鎖實現互斥,即一個共享資源,同時最多只能有一個線程訪問;
- 互斥鎖 & 條件變量,實現多線程同步;
- 互斥鎖 & 信號量,實現多線程同步;
- 讀寫鎖,互斥鎖的升級版本。讀的部分,多線程可以并行訪問;寫的部分,同時最多只能有一個線程訪問。
- 可以通過固定vector的大小,避免動態擴容(無push_back)來做到 lock-free
互斥不一定同步,同步包含互斥
什么是線程安全容器
線程安全容器是可以支持在多個線程并發訪問的STL容器。在多線程程序中使用線程安全容器可以保證數據操作的正確性和安全性。C++ STL庫提供了一些線程安全容器(適配器),包括std::stack
和std::queue
,它們都是基于順序容器實現的。這些容器提供了多個線程的并發訪問功能。
為什么需要線程安全容器
在并發環境中,多個線程可能同時訪問同一資源。對于非線程安全的容器,在多線程的情況下容易出現數據競爭、死鎖等問題。線程安全容器可以避免這種問題的發生,保證程序的正確性。
讀寫鎖和互斥鎖有什么區別?
讀寫鎖讀的時候會加鎖嗎?
簡述讀寫鎖實現時的二次加鎖檢測,了解源碼
delete沒加[]會報錯嗎?
delete 釋放new分配的單個對象指針指向的內存
delete[] 釋放new分配的對象數組指針指向的內存
(1). 針對簡單類型 使用new分配后的不管是數組還是非數組形式內存空間用兩種方式均可 如:
int *a = new int[10];
delete a;
delete [] a;
此種情況中的釋放效果相同,原因在于:分配簡單類型內存時,內存大小已經確定,系統可以記憶并且進行管理,在析構時,系統并不會調用析構函數,它直接通過指針可以獲取實際分配的內存空間,哪怕是一個數組內存空間(在分配過程中 系統會記錄分配內存的大小等信息,此信息保存在結構體_CrtMemBlockHeader中,具體情況可參看VC安裝目錄下CRT\SRC\DBGDEL.cpp
(2). 針對類Class,兩種方式體現出具體差異?
當你通過下列方式分配一個類對象數組:
class A{
private:char *m_cBuffer;int m_nLen;
public:A(){ m_cBuffer = new char[m_nLen]; }~A() { delete [] m_cBuffer; }
};A *a = new A[10];delete a; ? ? ? ? //僅釋放了a指針指向的全部內存空間 //但是只調用了a[0]對象的析構函數 剩下的從a[1]到a[9]這9個用戶//自行分配的m_cBuffer對應內存空間將不能釋放 從而造成內存泄漏delete [] a; ? ? ?//調用使用類對象的析構函數釋放用戶自己分配內存空間并且//釋放了a指針指向的全部內存空間
所以總結下就是,如果ptr代表一個用new申請的內存返回的內存空間地址,即所謂的指針,那么:
delete ? ptr ? 代表用來釋放內存,且只用來釋放ptr指向的內存。?
delete[] ? rg ? 用來釋放rg指向的內存,!!還逐一調用數組中每個對象的destructor!!
對于像int/char/long/int*/struct等等簡單數據類型,由于對象沒有destructor,所以用delete 和delete [] 是一樣的!但是如果是C++對象數組就不同了!
vector和list的區別
vector 擁有一塊連續的內存,因此支持隨機訪問,如果需要高效率的訪問,而不在乎插入和刪除的效率,使用vector
list擁有一段不連續的內存空間,如果需要高效率的插入和刪除,而不關心訪問效率,使用list
C++程序生成可執行程序的流程
預編譯-編譯-匯編-鏈接
C++遇到庫不存在時可以編譯嗎?
缺少動態庫,可執行文件不能運行,但能通過編譯
虛函數表實現思路
對于虛函數表來說,在編譯的過程中編譯器就為含有虛函數的類創建了虛函數表,并且編譯器會在構造函數中插入一段代碼,這段代碼用來給虛函數指針賦值。因此虛函數表是在編譯的過程中創建。
?對于虛函數表指針來說,由于虛函數表指針是基于對象的,所以對象在實例化的時候,虛函數表指針就會創建,所以是在運行時創建。由于在實例化對象的時候會調用到構造函數,所以就會執行虛函數表指針的賦值代碼,從而將虛函數表的地址賦值給虛函數表指針。