[英]c++ memory access violation
我正在學習C ++,目前的工作遇到很多麻煩。 到目前為止,我已經完成了很多工作。 但是,由於我認為我對幕后發生的事情知之甚少,所以我最近的進展非常緩慢。
我在以下代碼中嘗試做的是:
我得到的錯誤如下:
類3.exe中0x00a323e3的未處理異常:0xC0000005:訪問沖突讀取位置0xcdcdcdcd。
我很確定在嘗試將ammoArray[i]
設置為值時會發生錯誤。 但是我不知道為什么給我,我的代碼可以很好地編譯。 我玩了一下,在一種情況下,我得到它來存儲bDamage
和sDamage
的內存地址,然后打印出數組中每個元素的內存地址。 我想要做的是存儲bDamage
和sDamage
持有的值。
現在我的問題是:
為什么ammoArray
不存儲bDamage
和sDamage
的值而不是數組元素的內存地址? 以及如何存儲它們?
這是我的Main.cpp:
#include <cstdlib>
#include "Ammunition.h"
#include "AmmunitionManager.h"
#include "Bullet.h"
#include "Game.h"
#include "Pistol.h"
#include "Player.h"
#include "Point.h"
#include "Shell.h"
#include "Shotgun.h"
#include "WeaponManager.h"
#include "Weapons.h"
using namespace std;
void main()
{
Ammunition amVar;
AmmunitionManager *var = new AmmunitionManager();
amVar.setBDamage(6);
amVar.setSDamage(2);
var->FillAmmoArray(amVar.getSDamage(),amVar.getBDamage());
system("PAUSE");
}
這是相關類的.h文件:
#ifndef AMMUNITIONMANAGER_H
#define AMMUNITIONMANAGER_H
#include "Point.h"
#include "Ammunition.h"
class AmmunitionManager
{
public:
AmmunitionManager();
AmmunitionManager(int,int);
~AmmunitionManager();
void FillAmmoArray(int,int);
private:
Ammunition Ammo;
int **ammoArray;
};
#endif
這是相關類的.cpp文件:
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "AmmunitionManager.h"
#include "Point.h"
#include "Ammunition.h"
using namespace std;
AmmunitionManager::AmmunitionManager()
{
}
AmmunitionManager::AmmunitionManager(int sDamage,int bDamage)
:Ammo(sDamage,bDamage)
{
cout << "Filling ammo reservoir." << endl;
ammoArray = new int* [10];
}
void AmmunitionManager::FillAmmoArray(int sDamage,int bDamage)
{
srand(time(NULL));
int *holdS = &sDamage;
int *holdB = &bDamage;
if(ammoArray)
{
for(int i = 0;i < 9;i++)
{
int randC = rand() % 2 + 1;
if(randC == 1)
{
cout << "Was: " << ammoArray[i] << endl;//I am getting the error here.
ammoArray[i] = holdS;
cout << "Is: " << ammoArray[i] << endl;
}
if(randC == 2)
{
cout << "Was: " << ammoArray[i] << endl;//I am getting the error here.
ammoArray[i] = holdB;
cout << "Is: " << ammoArray[i] << endl;
}
}
}
}
AmmunitionManager::~AmmunitionManager()
{
*ammoArray = 0;
if(ammoArray)
{
delete [] ammoArray;
}
}
問題是您使用默認構造函數初始化AmmunitionManager
:
AmmunitionManager *var = new AmmunitionManager();
在默認構造函數中,您什么也不做,因此ammoArray
可以包含任何值。 最好將所有數據初始化為其默認值:
AmmunitionManager::AmmunitionManager() : Ammo(), ammoArray(NULL/* or nullptr for C++11 */)
{
}
現在,如果您要求
var->FillAmmoArray(amVar.getSDamage(),amVar.getBDamage());
由於ammoArray
為NULL,它將立即退出。 也許您還是想初始化ammoArray
,所以默認構造函數也應該具有其初始化:
AmmunitionManager::AmmunitionManager() : Ammo()
{
ammoArray = new int* [10];
}
srand
也只能調用一次,因此最好放置此代碼
srand(time(NULL));
在main()
或保證僅執行一次的任何其他模塊中。
在析構函數中,不需要為零*ammoArray=0
,它實際上將0放置在該數組的第一個元素上(就是這樣),無論如何都將其刪除。 並假設ammoArray
為NULL,訪問*ammoArray
會導致另一個分段錯誤。
另外,也無需在刪除之前檢查ammoArray
beibg NULL。 該標准允許“ delete
” NULL指針。 delete
只會返回而不執行任何操作。
一般說明
最好使用(更安全,更容易維護) std::vector
而不是(動態)數組和智能指針,而不是平面數組。
我沒有收到任何錯誤(VS2013)。 但是存儲的值是sDamage和bDamage的地址。
您是否正確使用AmmunitionManager(int sDamage,int bDamage)
作為用於創建AmmunitionManager對象的構造函數? 從我所看到的,你不是。
除此之外,請問您為什么要使用諸如**ammoArray
類的奇異構造而不是例如簡單的vector<int>
? 我猜這是您分配的一部分,但我只是想確保自己沒有遺漏任何東西。
我這樣稱呼對象:
int _tmain(int argc, _TCHAR* argv[])
{
AmmunitionManager* tc = new AmmunitionManager(5,10);
tc->FillAmmoArray(10,10);
return 0;
}
為什么ammoArray不存儲bDamage和sDamage的值而不是數組元素的內存地址?
因為您說過應該存儲地址。
這是一個指向指針的指針:
int **ammoArray;
這是一個指針數組:
ammoArray = new int* [10];
以及如何存儲它們?
通過執行以下操作:
int *ammoArray;
和這個:
ammoArray = new int [10];
並相應地調整FillAmmoArray
。
默認構造函數應如下所示:
AmmunitionManager::AmmunitionManager()
: ammoArray(nullptr)
{
}
析構函數應如下所示:
AmmunitionManager::~AmmunitionManager()
{
delete [] ammoArray;
}
而且你只應該打電話給srand
一次。
通常在main
的開頭完成。
如果不進行構建和調試,回答起來會有些棘手,但是讓我印象深刻的第一件事是:為什么整個都使用int
指針( *
)?
為什么不只是將數組作為指針:
int *ammoArray;
並設置其他int
-instances(刪除指針- *
和( &
)的address-of
)?
問候
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.