2014-09-23 4 views
0

Так что для назначения мне нужно создать программу, которая создаст магические квадраты, когда пользователь вводит нечетное число, у меня большая часть программы выполнена, но по какой-то причине, когда я пытаюсь заполнить квадраты Я получаю Необработанное исключение в 0x00326315 в magic square.exe: 0xC0000005: Место для обнаружения нарушения доступа 0x00000000Создание 2d динамического массива с указателями

Я использую классы и объявляю квадрат как int ** square;

Вот код

#include<iostream> 
#include<iomanip> 
#include"MagicSquare.h" 

using namespace std; 

MagicSquare::MagicSquare(): size(0), maxNum(0), row(0), col(0), curNum(0) //Constructor initialize variables 
{ 
} 

MagicSquare::~MagicSquare()        //Destructor 
{ 
for (int i = 0; i < size; i++) 
{ 
    delete[] square[i]; 
} 
delete[] square;                   //Delete the dynamically allocated memory 
} 
void MagicSquare::getSize() //Get the size of the magic square 
{ 
    cout << "Please enter an odd number for the number of rows/columns: "; 
    cin >> size; 
    while (size % 2 == 0) //Check to see if the number entered is odd 
    { 
     cout << "The number you entered is not odd, please enter an odd number: "; 
     cin >> size; 
    } 

    int **square = new (nothrow) int*[size]; 
    for (int i = 0; i < size; i++) 
    { 
     square[i] = new (nothrow) int[size]; 
    } 
    maxNum = size * size; 
    iCount = new (nothrow) int[size]; 
    jCount = new (nothrow) int[size]; 
} 

void MagicSquare::populateSquare() 
{ 
    for (int i = 0; i < size; i++) 
    { 
     for (int j = 0; j < size; j++) 
     { 
      square[i][j] = 0;  //This is where the error occurs 
     } 
    } 
    curNum = 1; 
    col = (size - 1)/2; 
    square[row][col] = curNum; 
    curNum += 1; 
    for (int i = 1; i <= maxNum; i++) 
    { 
     row = row - 1; 
     col = col + 1; 
     if (col >= size) 
      col = 0; 
     if (row < 0) 
      row = size - 1; 
     square[row][col] = curNum; 
     curNum += 1; 
    } 
} 

Заголовочный файл

class MagicSquare 
{ 
private: 
int **square; 
int size; 
int maxNum; 
int row; 
int col; 
int curNum; 
int *iCount; 
int *jCount; 

public: 
MagicSquare(); 
~MagicSquare(); 
void getSize(); 
void populateSquare(); 
void printSquare(); 
}; 

исходный файл

#include"MagicSquare.h" 
#include<iostream> 


using namespace std; 


int main() 
{ 
MagicSquare mySquare; 

int choice = 1; 
while (choice == 1) 
{ 
    mySquare.getSize(); 
    mySquare.populateSquare(); 
    mySquare.printSquare(); 

    cout << "\n\nWould you like to create another magic square? 1 for yes, 0 for no: "; 
    cin >> choice; 
    while (choice != 1 || choice != 0) 
    { 
     cout << "\nInvalid input: \nWould you like to create another magic square? 1 for yes, 0 for no: "; 
     cin >> choice; 
    } 
} 

system("pause"); 

return 0; 
} 
+3

Почему вы используете 'новый (nothrow) 'без проверки возвращаемого значения? Кроме того, дайте нам то, что компилируется. – tillaert

+0

Учитель требует этого, я обычно не использую (nothrow) – JBoyden

+2

Ваш учитель ДЕЙСТВИТЕЛЬНО говорит, что вы не должны проверять результат из 'нового', или просто чтобы вы использовали' nothrow'? Если это так, вы должны СЕРЬЕЗНО рассмотреть возможность поиска другого образования, так как это немного безумие. (Я как раз собирался написать что-то похожее на то, что написал tillaert, когда оно появилось) –

ответ

2

Вы определяете локальную переменную square в методе getSize() здесь:

int **square = new (nothrow) int*[size];.

Таким образом, вы создаете пространство для локальной переменной, но никогда не для поля класса.

Изменить эту строку

square = new (nothrow) int*[size];

также серьезно рассмотреть вопрос о проверке результатов вызовов.

+0

Спасибо, что сработало. Я ищу, как проверить результаты сейчас. – JBoyden

1

Точка доступа к нарушениям доступа 0x00000000 сообщает вам, что вы пытаетесь получить доступ к указателю NULL. Причина может заключаться в том, что по крайней мере один вызов new не удался. вы должны проверить при распределении массива:

int **square = new (nothrow) int*[size]; 
if(square == NULL) 
    //Handle error here 
for (int i = 0; i < size; i++) 
{ 
    square[i] = new (nothrow) int[size]; 
    if(square == NULL) 
     //Handle error here 
} 

Но я думаю, что это не причина. Если бы я увидел это правильно, у вас есть две функции:

void MagicSquare::getSize() 
void MagicSquare::populateSquare() 

Но int **square создается в GETSIZE, поэтому, если вы звоните заполнить квадрат, эта переменная больше не существует.

если ваш класс:

class MagicSquare 
{ 
private: 
    int **square; 
public: 
    //Methods 
} 

в GETSIZE вы должны сохранить адрес в переменной класса члена, а не локальная вы только что создали:

square = new (nothrow) int*[size]; //without int ** 
Смежные вопросы