##沒有躲過的坑--0xC0000005: 讀取位置 xxx時發生訪問沖突
Bjarne Stroustrup老爺子說過:?
**“C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off.”**
最近的工程時不時的出現0xC0000005: 讀取位置 xxx時發生訪問沖突,導致崩潰。
先看看下面的程序:
~~~
#include<iostream>
#include <string>
int main()
{
char * p1 = (char *)malloc(sizeof(char) * 20);
char p3[20] = "igkl";
char * p2 = "efgh";
p1 = "abcd"; //p1指向字符串"abcd"的首地址, 而不是把"abcd"拷貝到malloc開辟的內存塊中
strcat(p1, p2); //報錯: 0xC0000005異常,訪問沖突
strcat(p3, p2); //正確
std::cout << p1 << std::endl;
std::cout << p2 << std::endl;
std::cout << p3 << std::endl;
std::cout << p2 << std::endl;
//釋放內存
free(p1);
p1 = NULL;
return 0;
}
~~~
上面的程序在運行的時候就會報錯,調試分析:
因為指針變量p1(0x00d7576c)所指向的字符串常量“abcd”后面,也即字符’d’的地址是 0x00d7576c+3=0x00d7576f 。而它后面以地址 0x00d75770 開始的內存塊是不屬于指針變量p1的,沒有訪問權限,所以把拷貝自指針變量p2(0x00d75774)指向的字符串“efgh”到以 0x00d75770 為起始地址的內存塊中會報錯。
如果這樣修改:
~~~
char p3[20] = "igkl";
char * p1 = (char *)malloc(sizeof(char) * 20);
p1 = p3;
char * p2 = "efgh";
strcat(p1, p2); //正確
strcat(p3, p2); //正確
~~~
可以把語句 p1 = “abcd”; 改成 p1 = p3;,然后直接使用 strcat( p1, p2 );,這樣是合法的。
博客[C++“讀取位置 0x****** 時發生訪問沖突”的可能原因](http://blog.csdn.net/pkueecser/article/details/6066850 "0xC0000005可能的錯誤")?
有指出了一種情況:
malloc一個100內存的空間用于讀入文件,當文件的大小超過100時,并且程序中再使用100之后的內存時,就會產生“0xC0000005: 讀取位置 xxx時發生訪問沖突”這樣的錯誤。
還有可能產生的原因:?
**申請的內存沒有釋放**?
new后必須delete?
malloc后必須free?
創建內核對象(比如CreateFile,CreateMutex,CreateThread),后必須釋放內核對象句柄.?
創建內存映射文件,CreateFileMapping,MapViewOfFile后必須CloseHandle(),UnMapviewofFile?
創建GDI對象后,比如LoadIcon,LoadImage,CreateImageList等等,必須Destroy掉?
創建DC后,比如GetDC(), 必須釋放DC句柄?
保留虛擬地址空間 VirtualAlloc(),然后提交物理存儲器后,必須釋放掉
**出現死循環導致內存泄露**
**所有的第三方類庫存在內存泄露相關的BUG**
常見的溢出主要有:?
**內存分配未成功,卻使用了它。**?
常用解決辦法是,在使用內存之前檢查指針是否為NULL。如果指針p 是函數的參數,那么在函數的入口處用assert(p!=NULL)進行檢查。如果是用malloc 或new 來申請內存,應該用if(p==NULL)或if(p!=NULL)進行防錯處理。
**內存分配雖然成功,但是尚未初始化就引用它。**?
內存分配成功并且已經初始化,但操作越過了內存的邊界。?
例如在使用數組時經常發生下標“多1”或者“少1”的操作。特別是在for 循環語句中,循環次數很容易搞錯,導致數組操作越界。
**使用free 或delete 釋放了內存后,沒有將指針設置為NULL。導致產生“野指針”。**
程序中的對象調用關系過于復雜,實在難以搞清楚某個對象究竟是否已經釋放了內存,此時應該重新設計數據結構,從根本上解決對象管理的混亂局面。
不要忘記為數組和動態內存賦初值。防止將未被初始化的內存作為右值使用。
- 前言
- deprecated關鍵字
- 指針(內存泄露)
- 頭文件相互包含(Compiler error C2653: not a class or namespace name)
- 獲取一張圖片的width和height
- This function or variable may be unsafe.
- 智能指針陷阱
- wstring與string的轉換
- windows下chrome瀏覽器插件不能安裝
- 重定義關鍵字
- 正確釋放vector的內存
- 獲取設備環境HDC
- 抽象類不能實例化對象(但是你明明定義的不是抽象類)
- 重載賦值運算符的自我賦值
- 程序中的變量未初始化
- 成對使用new和delete時要采取相同的形式
- 意想不到的除數為零
- map的初始化(插入數據)
- 正則表達式截取字符串
- 捕獲窗口之外的鼠標消息(鉤子還是??)
- 類中的靜態成員變量(static or const static)
- 有if就要有else(一定成對)
- map查找結果處理
- 使用using namespace std的壞習慣
- new一個指針數組、以及創建動態二維數組
- 使用太多的全局變量
- 沒有及時break出for循環
- vector使用erase后迭代器變成野指針
- C++函數的默認參數(重新定義默認參數)
- 0xC0000005: 讀取位置 xxx時發生訪問沖突
- std::string初始化、最快速判斷字符串為空
- 你開發的軟件安裝在C盤Program Files (x86)下產生的異常