我想我有内存泄漏?

时间:2017-10-20 14:12:45

标签: c++

我正在尝试使用动态阵列进行骑士之旅,因为用户将能够实现他们自己的电路板尺寸,以及他们想要在电路板上启动骑士的位置。 然而,在我将所有内容更改为动态数组之前,我能够使用静态数组执行我的代码,但是现在每当我的代码执行时我都切换到动态数组,我相信内存泄漏并且程序崩溃了。我想知道我的解构器是否工作不正常?或者如果有不同的方法我必须删除动态数组? 我也想知道是否有办法使这个代码更有效,更确切地说使Move()函数更有效。感谢。

#include <iostream>
#include <iomanip>
#include "stdafx.h"
using namespace std;

class Knight
{
private:
int Tracker = 1;
int BoardSize;
int **Board = new int*[BoardSize];
public:
Knight(int s)
{
    BoardSize = s;
    for (int i = 0; i <= s -1; i++)
    {
        Board[i] = new int[s];
    }
    for (int i = 0; i <= s - 1; i++)
    {
        for (int j = 0; j <= s - 1; j++)
        {
            Board[i][j] = 0;
        }
    }
}
~Knight()
{
    for (int i = 0; i <= BoardSize - 1; i++)
    {
        delete[] Board[i];
    }
    delete[] Board;
}

void MarkUp(int &val)
{
    val = Tracker;
    Tracker++;
}

void MarkDown(int &val)
{
    val = 0;
    Tracker--;
}

bool PossibleMove(int &val)
{
    if (val == 0)
        return 1;
    else
        return 0;
}

void Display()
{
    for (int k = 0; k < (BoardSize * 5) + 1; k++)
    {
        cout << "-";
    }
    cout << endl;
    for (int i = 0; i <= BoardSize - 1; i++)
    {
        cout << "| ";
        for (int j = 0; j <= BoardSize - 1; j++)
        {
            cout << setw(2) << setfill('0') << Board[i][j] << " | ";
        }
        cout << endl;
        for (int k = 0; k < (BoardSize * 5) + 1; k++)
        {
            cout << "-";
        }
        cout << endl;
    }
    cout << endl << endl;
}

bool Move(int x, int y)
{
    if (Tracker > (BoardSize * BoardSize))
    {
        return true;
    }
    if (PossibleMove(Board[x][y])) {
        if ((x - 2 >= 0) && (y + 1 <= (BoardSize - 1)))
        {
            MarkUp(Board[x][y]);
            if (Move(x - 2, y + 1))
            {
                return true;
            }
            else
            {
                MarkDown(Board[x][y]);
            }
        }
        if ((x - 2 >= 0) && (y - 1 >= 0))
        {
            MarkUp(Board[x][y]);
            if (Move(x - 2, y - 1))
            {
                return true;
            }
            else
            {
                MarkDown(Board[x][y]);
            }
        }
        if ((x - 1 >= 0) && (y + 2 <= (BoardSize - 1)))
        {
            MarkUp(Board[x][y]);
            if (Move(x - 1, y + 2))
            {
                return true;
            }
            else
            {
                MarkDown(Board[x][y]);
            }
        }
        if ((x - 1 >= 0) && (y - 2 >= 0))
        {
            MarkUp(Board[x][y]);
            if (Move(x - 1, y - 2))
            {
                return true;
            }
            else
            {
                MarkDown(Board[x][y]);
            }
        }
        if ((x + 2 <= (BoardSize - 1)) && (y + 1 <= (BoardSize - 1)))
        {
            MarkUp(Board[x][y]);
            if (Move(x + 2, y + 1))
            {
                return true;
            }
            else
            {
                MarkDown(Board[x][y]);
            }
        }
        if ((x + 2 <= (BoardSize - 1)) && (y - 1 >= 0))
        {
            MarkUp(Board[x][y]);
            if (Move(x + 2, y - 1))
            {
                return true;
            }
            else
            {
                MarkDown(Board[x][y]);
            }
        }
        if ((x + 1 <= (BoardSize - 1)) && (y + 2 <= (BoardSize - 1)))
        {
            MarkUp(Board[x][y]);
            if (Move(x + 1, y + 2))
            {
                return true;
            }
            else
            {
                MarkDown(Board[x][y]);
            }
        }
        if ((x + 1 <= (BoardSize - 1)) && (y - 2 >= 0))
        {
            MarkUp(Board[x][y]);
            if (Move(x + 1, y - 2))
            {
                return true;
            }
            else
            {
                MarkDown(Board[x][y]);
            }
        }
    }
    return false;
}   
};

int main()
{
int size = 0;
int Row, Col;
int opt = 0;

do
{
    cout << "Welcome to Knights Tour!" << endl;
    cout << "1) Start the Tour." << endl;
    cout << "2) Quit." << endl;
    cin >> opt;

    switch (opt)
    {
    case 1:
    {
        cout << "Enter board size:" << endl;
        cin >> size;

        Knight K1(size);

        cout << "Enter Row:" << endl;
        cin >> Row;
        cout << "Enter Column: " << endl;
        cin >> Col;

        if (K1.Move(Row, Col))
        {
            cout << "\nOperation was Successful." << endl;
            cout << "Possible Solution:" << endl;
            K1.Display();
        }
        else
        {
            cout << "\nThat is not Possible." << endl;
        }
        cout << endl;
        break;
    }
    case 2:
    {
        exit(0);
        break;
    }
    default:
    {
        cout << "Not a Valid Option." << endl;
        cout << "Try Again Please." << endl;
        cout << endl;
        break;
    }
    }
} while (opt != 2);
return 0;
}

2 个答案:

答案 0 :(得分:3)

此代码无法正常工作:

int BoardSize;
int **Board = new int*[BoardSize];

BoardSize的值将是在为其分配的内存中发生的任何事情,因此new将尝试分配不可知的大小数组。

请勿使用手动编码的动态数组。使用std::vector;这就是它的用途。在现实生产代码中,您几乎从不使用动态分配的数组。您将使用其中一个标准容器。

答案 1 :(得分:1)

正如多人的评论中所指出的,内存泄漏不会导致崩溃(通常)。

问题是在构造函数内部,您为Board数组元素赋值。但是,您永远不会为Board数组本身分配内存。即当您执行Board[i] = new int[s];时,Board指向某个随机地址。这是因为在构造函数启动之前不会执行行int **Board = new int*[BoardSize];

所以以下内容应该有效:

class Knight {
  private:
    int BoardSize;
    int **Board;

  public:
    Knight (int s) {
      BoardSize = s;
      Board = new int*[BoardSize];

      // Remainder of code
    }
};

但是,我建议您使用std::vector代替。那么你根本不需要处理内存(de)分配。这可能看起来简洁如下:

#include <vector>

class Knight {
  private:
    int BoardSize;
    std::vector<std::vector<int>> Board;

  public:
    Knight (int s) : BoardSize(s), Board(s, std::vector<int>(s, 0)) { }
};

请注意,我在member initializer list

中初始化了类成员目录