这是程序
#include <iostream>
#include <time.h>
#include <conio.h>
#include <cstdlib>
#include <windows.h>
using namespace std;
const int widht = 117,height = 26;
class Paddle
{
private:
int y;
int originalY;
public:
Paddle()
{
y=height/2-2;
originalY=y;
}
inline int getY()
{
return y;
}
inline void moveUp()
{
y--;
}
inline void moveDown()
{
y++;
}
void checkWall()
{
if (y<0)
{
while (y<0)
{
y++;
}
}
else if (y>height)
{
while (y>height)
{
y--;
}
}
}
void Reset()
{
y=originalY;
}
};
class Ball
{
private:
int x,y;
int originalX,originalY;
public:
Ball()
{
x=widht/2;
y=height/2;
originalX=x;
originalY=y;
}
inline int getX()
{
return x;
}
inline int getY()
{
return y;
}
inline void moveRight()
{
x++;
}
inline void moveUpRight()
{
x++;
y--;
}
inline void moveDownRight()
{
x++;
y++;
}
inline void moveLeft()
{
x--;
}
inline void moveUpLeft()
{
y--;
x--;
}
inline void moveDownLeft()
{
y++;
x--;
}
inline void Reset()
{
x=originalX;
y=originalY;
}
};
class Manager
{
private:
int score1,score2;
int columns, rows;
public:
int p1y;
int p2y;
int ballX,ballY;
bool gameOver;
Manager()
{
gameOver = false;
}
void Draw(Paddle *p1,Paddle *p2,Ball *b)
{
system("cls");
p1y=p1->getY();
p2y=p1->getY();
ballX=b->getX();
ballY=b->getY();
for (int i=0;i<height;i++)
{
for (int j=0;j<widht;j++)
{
if (i==p1y && j==2)
{
cout << "\xDB";
}
else if (i==p1y+1 && j==2)
{
cout << "\xDB";
}
else if (i==p1y+2 && j==2)
{
cout << "\xDB";
}
else if (i==p1y+3 && j==2)
{
cout << "\xDB";
}
else if (i==p1y+4 && j==2)
{
cout << "\xDB";
}
else if (i==p2y && j==widht-1)
{
cout << "\xDB";
}
else if (i==p2y+1 && j==widht-1)
{
cout << "\xDB";
}
else if (i==p2y+2 && j==widht-1)
{
cout << "\xDB";
}
else if (i==p2y+3 && j==widht-1)
{
cout << "\xDB";
}
else if (i==p2y+4 && j==widht-1)
{
cout << "\xDB";
}
else if (i==ballX && j==ballY)
{
cout << "O";
}
cout << " ";
}
cout << endl;
}
cout << p1 -> getY();
}
void Input(Paddle *p1,Paddle *p2)
{
if (_kbhit())
{
switch(_getch())
{
case 'w':
p1->moveUp();
break;
case 's':
p1->moveDown();
break;
case 'i':
p2->moveUp();
break;
case 'k':
p2->moveDown();
break;
}
}
}
void Run(Paddle *p1,Paddle *p2, Ball *b)
{
while(!gameOver)
{
Draw(p1,p2,b);
Input(p1,p2);
Sleep(10);
}
}
};
int main()
{
Paddle *p1;
Paddle *p2;
Ball *b;
Manager *m;
m->Run(p1,p2,b);
return 0;
}
我无法理解为什么当我启动程序时(使用调试器)分段错误。 我认为原因是指针,因为在它完美运作之前(但没有修改值); 有任何提示吗?
答案 0 :(得分:2)
您从未为其分配任何内存而且您从未初始化
Paddle *p1;
Paddle *p2;
Ball *b;
Manager *m;
使用这些指针是undefined behavior。
您应该将所有对象更改为常规自动对象(如
),而不是使用指针Paddle p1;
Paddle p2;
Ball b;
Manager m;
然后通过函数而不是指针传递它们。
答案 1 :(得分:0)
Manager *m;
m->Run(p1,p2,b);
在为变量赋值之前,不能使用变量的值。您没有为m
分配值,但您可以立即使用它。这不可能正常工作。
代码Manager *m;
只声明一个名为m
的变量pointer to Manager
。但它还没有指出任何东西。
代码m->Run(p1,p2,b);
会调用Run
指向的Manager
上的m
方法。如果m
未指向类Manager
的实例,则执行此操作毫无意义。
答案 2 :(得分:0)
您尚未在主方法中指向Paddle
,Ball
或Manager
变量的指针中指定任何内容。
默认情况下,不会初始化并将指向内存中的某个位置,您的应用程序可能可以访问,也可能无法访问。当您访问它们并且内存不可访问时,您将获得您正在观察的访问冲突或段错误。
您可以采取两种方法。如果您更改主要内容如下:
int main()
{
Paddle p1;
Paddle p2;
Ball b;
Manager m;
m.Run(&p1,&p2,&b);
return 0;
}
然后,堆栈中将存在每个类的实例。由于应用程序在m.Run
返回后退出,因此使用此方法是安全的,因为对象的生命周期比Run
调用的代码长。
或者,您可以在堆上分配它们。在这种情况下,您可以使用:
int main()
{
std::unique_ptr<Paddle>( new Paddle );
std::unique_ptr<Paddle>( new Paddle );
std::unique_ptr<Ball>( new Ball );
std::unique_ptr<Manager>( new Manager );
m->Run(p1.get(),p2.get(),b.get());
return 0;
}
unique_ptr
将保存指向堆上分配的Paddle
等的指针,并在main
方法返回后自动为您清理它。