指针给出了seg错误

时间:2016-04-07 18:21:10

标签: c++

这是程序

    #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;
    }

我无法理解为什么当我启动程序时(使用调试器)分段错误。 我认为原因是指针,因为在它完美运作之前(但没有修改值); 有任何提示吗?

3 个答案:

答案 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)

您尚未在主方法中指向PaddleBallManager变量的指针中指定任何内容。

默认情况下,不会初始化并将指向内存中的某个位置,您的应用程序可能可以访问,也可能无法访问。当您访问它们并且内存不可访问时,您将获得您正在观察的访问冲突或段错误。

您可以采取两种方法。如果您更改主要内容如下:

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方法返回后自动为您清理它。