C++讀取訪(fǎng)問(wèn)權(quán)限沖突引發(fā)異常問(wèn)題的原因分析
用C++寫(xiě)代碼時(shí)經(jīng)常會(huì)遇到“引發(fā)了異常: 讀取訪(fǎng)問(wèn)權(quán)限沖突。”這樣的錯(cuò)誤提示,這種情況產(chǎn)生原因主要有兩點(diǎn):
一、訪(fǎng)問(wèn)數(shù)組越界
當(dāng)采用線(xiàn)性表的順序結(jié)構(gòu),例如順序表、隊(duì)列、棧等,用數(shù)組存儲(chǔ)數(shù)據(jù)時(shí),若將要讀取數(shù)據(jù)的位置超出了當(dāng)前數(shù)組的長(zhǎng)度,就會(huì)發(fā)生數(shù)組訪(fǎng)問(wèn)越界的狀況。
可這并不會(huì)造成編譯錯(cuò)誤,也就是說(shuō),編譯器并不會(huì)在你編譯的時(shí)候就指出你訪(fǎng)問(wèn)數(shù)組越界了,這個(gè)時(shí)候可能還是“0 errors,0 warnings”

你還在暗暗慶幸自己的代碼沒(méi)有bug,但是當(dāng)你運(yùn)行之后就會(huì)拋出訪(fǎng)問(wèn)權(quán)限沖突的異常。
例如:下面這段對(duì)隊(duì)列和棧的操作
struct Stack //這里定義了一個(gè)棧的結(jié)構(gòu)
{
int data[maxSize]; //定義存儲(chǔ)棧中元素的數(shù)組
int top; //定義棧頂指針
};
struct Queue //這里定義了一個(gè)隊(duì)列的結(jié)構(gòu)
{
int elements[2000]; //定義一個(gè)長(zhǎng)度為2000的數(shù)組存放隊(duì)列中的元素
int front; //定義隊(duì)頭指針
int rear; //定義隊(duì)尾指針
};
while (queueA->front < queueA->rear || queueB->front < queueB->rear)
{
queueA->front++;
inStack(stack, queueA->elements[queueA->front]);
outStack(stack, queueA);
queueB->front++;
inStack(stack, queueB->elements[queueB->front]);
outStack(stack, queueB);
}
//inStack函數(shù)實(shí)現(xiàn)出隊(duì)后進(jìn)棧操作
//outStack函數(shù)實(shí)現(xiàn)出棧后入隊(duì)操作,入隊(duì)后隊(duì)尾指針后移
編譯成功沒(méi)有報(bào)錯(cuò),但是運(yùn)行后拋出了讀取訪(fǎng)問(wèn)權(quán)限沖突的異常

我們查看此時(shí)局部變量的狀態(tài)可以發(fā)現(xiàn),隊(duì)列A 的隊(duì)頭指針和隊(duì)尾指針都指向了異常的下標(biāo)

這顯然發(fā)生了訪(fǎng)問(wèn)越界的情況,因?yàn)殚L(zhǎng)度為2000的數(shù)組,下標(biāo)的取值應(yīng)該是0~1999。
后來(lái),發(fā)現(xiàn)錯(cuò)誤出在while循環(huán)判定的條件。本意上是當(dāng)A、B之間任意一個(gè)隊(duì)列中的元素為空的時(shí)候就跳出循環(huán),但是錯(cuò)將判定條件中的邏輯且寫(xiě)成了邏輯或,導(dǎo)致遲遲不能跳出循環(huán),最終隊(duì)列A的隊(duì)頭指針和隊(duì)尾指針在不斷的循環(huán)操作中超出了數(shù)組邊界,發(fā)生了讀取訪(fǎng)問(wèn)權(quán)限沖突的異常。

將while的判定條件修改后,程序可正常運(yùn)行。
所以遇到讀取訪(fǎng)問(wèn)權(quán)限沖突的提示,如果異常發(fā)生在讀取數(shù)組中數(shù)據(jù)的時(shí)候,可以?xún)?yōu)先考慮是否是因?yàn)槟撤N操作不當(dāng)導(dǎo)致訪(fǎng)問(wèn)數(shù)組越界了。
二、空指針異常
這主要發(fā)生在通過(guò)指針讀取數(shù)據(jù)時(shí),比如在使用鏈表的過(guò)程中。
示例:鏈表中的操作
struct Node //這里定義了一個(gè)結(jié)點(diǎn)
{
int data;
Node* next;
};
LinkListInvert::LinkListInvert(int arg[],int n)
{ //重載構(gòu)造函數(shù)對(duì)鏈表進(jìn)行初始化
Node* r = first;
Node* s = nullptr;
for (int i = 0; i < n; i++)
{
s = new Node;
s->data = arg[i];
r->next = s;
r = s;
}
r->next = nullptr;
}
代碼編譯無(wú)錯(cuò)誤,運(yùn)行后發(fā)生讀取訪(fǎng)問(wèn)權(quán)限異常

這里不難看出是因?yàn)闆](méi)有初始化first指針,使得first指針成為了一個(gè)空指針,指向了一個(gè)不確定的值,隨后進(jìn)行的操作
Node* r = first;
使r指針也成為了一個(gè)空指針,在進(jìn)行接下來(lái)的操作時(shí)就拋出了讀取權(quán)限沖突的異常。
LinkListInvert::LinkListInvert(int arg[],int n)
{
first = new Node; //此處為修改的地方,對(duì)first初始化
Node* r = first;
Node* s = nullptr;
for (int i = 0; i < n; i++)
{
s = new Node;
s->data = arg[i];
r->next = s;
r = s;
}
r->next = nullptr;
}
而修改的方式也很簡(jiǎn)單,對(duì)first指針進(jìn)行初始化后即可運(yùn)行成功。
類(lèi)似的,由指針未初始化而引發(fā)的讀取訪(fǎng)問(wèn)權(quán)限異常,還會(huì)給出諸如 0XCCCCCCCC、0xCDCDCDCD的異常提示。

當(dāng)然,不止鏈表,空指針異常還會(huì)出現(xiàn)在很多其他情況下,比如在數(shù)據(jù)庫(kù)查詢(xún),指針未初始化時(shí)也會(huì)產(chǎn)生空指針異常。
總結(jié)
到此這篇關(guān)于C++讀取訪(fǎng)問(wèn)權(quán)限沖突引發(fā)異常問(wèn)題的文章就介紹到這了,更多相關(guān)C++讀取訪(fǎng)問(wèn)權(quán)限沖突內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言深入回顧講解結(jié)構(gòu)體對(duì)齊
C 數(shù)組允許定義可存儲(chǔ)相同類(lèi)型數(shù)據(jù)項(xiàng)的變量,結(jié)構(gòu)是 C 編程中另一種用戶(hù)自定義的可用的數(shù)據(jù)類(lèi)型,它允許你存儲(chǔ)不同類(lèi)型的數(shù)據(jù)項(xiàng),本篇讓我們來(lái)了解C 的結(jié)構(gòu)體內(nèi)存對(duì)齊2022-06-06
C++ 智能指針的模擬實(shí)現(xiàn)實(shí)例
這篇文章主要介紹了C++ 智能指針的模擬實(shí)現(xiàn)實(shí)例的相關(guān)資料,智能指針是一個(gè)類(lèi),它把普通指針?lè)庋b起來(lái),能實(shí)現(xiàn)和普通指針同樣的功能。,需要的朋友可以參考下2017-07-07
從txt中讀入數(shù)據(jù)到數(shù)組中(fscanf)的實(shí)現(xiàn)代碼
下面小編就為大家?guī)?lái)一篇從txt中讀入數(shù)據(jù)到數(shù)組中(fscanf)的實(shí)現(xiàn)代碼。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12
C語(yǔ)言開(kāi)發(fā)之歸并排序詳解及實(shí)例
這篇文章主要介紹了 C語(yǔ)言開(kāi)發(fā)之歸并排序詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-03-03
Qt私有信號(hào)實(shí)現(xiàn)(private signal)
在使用Qt信號(hào)槽機(jī)制的時(shí)候,有時(shí)候我們需要一個(gè)信號(hào)只能由類(lèi)內(nèi)發(fā)出,而不允許使用該類(lèi)對(duì)象的用戶(hù)發(fā)出,此時(shí)就需要私有信號(hào)的支持,本文主要介紹了Qt私有信號(hào)實(shí)現(xiàn)(private signal),感興趣的可以了解一下2023-10-10
C語(yǔ)言基礎(chǔ)之二分查找知識(shí)最全匯總
這篇文章主要介紹了C語(yǔ)言基礎(chǔ)之二分查找知識(shí)最全匯總,文中有非常詳細(xì)的二分查找基礎(chǔ)知識(shí)詳解,對(duì)正在學(xué)習(xí)C語(yǔ)言基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下2021-04-04
C C++算法題解LeetCode1408數(shù)組中的字符串匹配
這篇文章主要為大家介紹了C C++算法題解LeetCode1408數(shù)組中的字符串匹配示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10

