基本上我在这一点上要做的是构建一个程序,允许你从3个不同的类(Tank,Mele,Ranged)中挑选,当你选择这个类时,你会给它一个20或更少的名字字符。在挑选了5个课程并给每个冠军一个名字后,它将打印出你选择的每个课程的名称和健康状况。代码如下:
#include "Driver.h"
#include <stdio.h>
#include "Mele.h"
#include "Ranged.h"
#include "Tank.h"
int main(void)
{
Champion *champ[5];
int i, choice;
printf("Enter the number for which class you would like to add to your team\n");
for(i = 0; i <= 4; i++)
{
char name[20];
//printf("Enter the number for which class you would like to add to your team");
printf("1 = Tank\n");
printf("2 = Ranged\n");
printf("3 = Mele\n");
scanf_s("%d", &choice);
if(choice == 1)
{
printf("Give him a name!\n");
scanf("%s", name);
champ[i] = new Tank(name);
}
else if(choice == 2){
printf("Give him a name!\n");
scanf("%s", name);
champ[i] = new Ranged(name);
}
else if(choice == 3){
printf("Give him a name!\n");
scanf("%s", name);
champ[i] = new Mele(name);
}
else
{
printf("You did not enter a number between 1 and 3 please try again!\n");
i = i - 1;
}
}
for(i = 0; i <= 4; i++)
{
printf("%s has %f health", champ[i]->getName(), champ[i]->getHealth());
}
return 0;
}
这是主要功能
冠军班看起来像:
Champion::Champion(void)
{
}
Champion::Champion(char name1[])
{
name = name1;
}
char* Champion::getName(void)
{
return name;
}
double Champion::getHealth(void)
{
return health;
}
int Champion::getFluid(void)
{
return fluid;
}
double Champion::getArmor(void)
{
return armor;
}
double Champion::getSpecialA(void)
{
return specialA;
}
double Champion::getDamage(void)
{
return physDamage;
}
void Champion::setHealth(double health1)
{
health = health1;
}
void Champion::setFluid(int fluid1)
{
fluid = fluid1;
}
void Champion::setArmor(double armor1)
{
armor = armor1;
}
void Champion::getSpecialA(double specialA1)
{
specialA = specialA1;
}
void Champion::setDamage(double physDamage1)
{
physDamage = physDamage1;
}
然后我还有4个名为Tank,Ranged和Mele的课程;所有这些都继承自冠军并拥有与冠军相同的设置。当我运行程序时,我得到了这个:
'dragons_rage.exe': Loaded 'C:\Users\Tom\Documents\Visual Studio 2010\Projects\dragons_rage\Debug\dragons_rage.exe', Symbols loaded.
'dragons_rage.exe': Loaded 'C:\Windows\SysWOW64\ntdll.dll', Cannot find or open the PDB file
'dragons_rage.exe': Loaded 'C:\Windows\SysWOW64\kernel32.dll', Cannot find or open the PDB file
'dragons_rage.exe': Loaded 'C:\Windows\SysWOW64\KernelBase.dll', Cannot find or open the PDB file
'dragons_rage.exe': Loaded 'C:\Windows\SysWOW64\msvcr100d.dll', Symbols loaded.
First-chance exception at 0x5dfc14cf (msvcr100d.dll) in dragons_rage.exe: 0xC0000005: Access violation reading location 0xcdcdcdcd.
Unhandled exception at 0x5dfc14cf (msvcr100d.dll) in dragons_rage.exe: 0xC0000005: Access violation reading location 0xcdcdcdcd.
The program '[516] dragons_rage.exe: Native' has exited with code -1073741819 (0xc0000005).
我不确定这些错误是什么以及它们意味着什么,如果我能得到一些帮助那将是非常棒的谢谢!!!!
答案 0 :(得分:4)
突然出现的一件事是Champion构造函数:
Champion::Champion(char name1[])
{
}
这对字符数组没有任何作用 - 它不会初始化任何“name”成员。如果名字稍后发出,是否为空,或者更糟,垃圾?您可能需要将该参数复制到您的成员变量中,因此您可以使用稍后可以使用的名称。
答案 1 :(得分:4)
变量char name [20]在离开第一个for()
后无效您应该将构造函数中数组的值复制到Champion中的数组中,或者为名称动态分配内存。
这是一个选择:
#include <stdio.h>
#include <string.h>
class Champion {
char name[20];
public:
Champion(const char theName[],int size ){
for( int i=0;i < size; i++ ){
name[i] = theName[i];
}
}
const char* getName(){
return name;
}
};
int main(int argc, const char* argv[]){
Champion *c;
const char name[] = "vamos";
c = new Champion(name,strlen(name));
printf("%s",c->getName());
return 0;
}
答案 2 :(得分:1)
你的循环只运行4次,所以最后一个冠军指针永远不会被初始化。
for(i = 0; i < 4; i++)
应改为:
for(i = 0; i < 5; i++)
此外,没有任何Champion类成员在构造函数中初始化,因此读取它们将导致未定义的行为。
您编写的代码或多或少是C类。查找std :: string,它将使您的代码更简单,更正确。就像现在一样,你的程序包含多个缓冲区溢出漏洞和悬空指针。
如果我是邪恶的,我会创建一个名称超过20个字符的坦克,可能会导致程序崩溃或者更糟糕的是,通过覆盖文本段来执行任意代码。
答案 3 :(得分:0)
检查
return name;
in
Champion::getName()
名称定义在哪里? 它被初始化了吗?
在构造函数中执行name = name1
时,您只是复制指针。
对于程序,这是指向for循环中的局部变量的指针。
一旦你离开那个for循环,那个变量就超出了范围。
您应该使用std::string::copy()或strcpy()复制字符串。
答案 4 :(得分:0)
习惯将指针成员设置为0(NULL)是构造函数,如果它们没有指向堆上或堆栈上的任何地址。这样做可以使您免于0xcc ...无效地址。如果你完成了指针,即使指针是双指针的一部分,在释放它指向的对象后将其设置回0。编写代码是您的责任。另一种选择是改为使用托管内存编程语言。
使用您的代码,它是
Champion** champ = (Champion**)malloc(sizeof(Champion*) * 5);
// or
Champion** champ = (Champion**)calloc(5, sizeof(Champion*));
// or
Champion** champ = new Champion*[5];
你选择分配冠军双指针的方式取决于你。我更喜欢(Champion**)malloc(sizeof(Champion*) * 5)
因为我习惯于C风格编码。