我正在学习C ++,而且我目前的作业遇到了很多麻烦。到目前为止,我已经完成了很多。然而,由于我认为我对幕后发生的事情了解不多,我最近的进展非常缓慢。
我在以下代码中尝试做的是:
我得到的错误如下:
Class 3.exe中0x00a323e3处的未处理异常:0xC0000005:Access 违规阅读地点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;
}
}
答案 0 :(得分:0)
问题是您使用默认构造函数初始化v2b
:
AmmunitionManager
在默认构造函数中,您不执行任何操作,因此AmmunitionManager *var = new AmmunitionManager();
可能包含任何值。
最好将所有数据初始化为默认值:
ammoArray
现在,如果你要求
AmmunitionManager::AmmunitionManager() : Ammo(), ammoArray(NULL/* or nullptr for C++11 */)
{
}
它将立即退出,因为var->FillAmmoArray(amVar.getSDamage(),amVar.getBDamage());
为NULL。
或者你可能想要初始化ammoArray
,所以默认构造函数也应该初始化:
ammoArray
同样AmmunitionManager::AmmunitionManager() : Ammo()
{
ammoArray = new int* [10];
}
只应调用一次,因此最好放置此代码
srand
在srand(time(NULL));
或任何其他保证只执行一次的模块中。
在析构函数中,没有必要将main()
置零,它实际上将0放在该数组的第一个元素上(并且它就是它),你仍然删除它。并且假设*ammoArray=0
为NULL,访问ammoArray
会导致另一个分段错误。
在删除之前,无需检查*ammoArray
beibg NULL。该标准允许ammoArray
&#39; NULL指针。 delete
只会在没有做任何事情的情况下返回。
一般说明
最好使用(更安全,更易于维护)std::vector
代替(动态)数组和smart pointers代替扁平数组。
答案 1 :(得分:0)
我没有收到任何错误(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;
}
答案 2 :(得分: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
的开头完成。
答案 3 :(得分:-1)
在没有构建和调试的情况下回答有点棘手,但首先让我感到惊讶的是:为什么你在整个过程中使用指针(*
)到int
?
为什么不把数组作为指针:
int *ammoArray;
并制作其他int
- 个实例(删除指针 - *
和address-of
'(&
))?
此致