2015-04-14 4 views
2

Еще одна проблема с магическим квадратом. Я создаю нечетную магическую квадратную программу на C++, и по какой-то причине программа продолжает давать ошибку ошибки сегментации и уходит. Вот код:Magic Square in C++

#include <iostream> 

using std::cin; 
using std::cout; 

#include <cstring> 

using std::memset; 

int *generateOddSquare(int n) { 
    if (n % 2 != 0 && n >= 3) { 
     int row = 0, col = n/2, square = n * n; 
     int **matrix = new int *[n], *dest = new int[square]; 

     memset(matrix, 0, sizeof(matrix[0][0]) * square); 

     for (int i = 1; i <= square; i++) { 
      matrix[row][col] = i; 

      if (i % n == 0) 
       row++; 
      else { 
       if (row == 0) 
        row = n - 1; 
       else 
        row--; 

       if (col == (n - 1)) 
        col = 0; 
       else 
        col++; 
      } 
     } 

     for (int i = 0; i < n; i++) { 
      for (int j = 0; j < n; j++) { 
       dest[(i * n) + j] = matrix[i][j]; 
      } 
     } 

     return dest; 
    } else 
     return NULL; 
} 

int main() { 
    int *arr = generateOddSquare(3); 

    for (int i = 0; i < 9; i++) { 
     cout << arr[i] << "\n"; 
    } 
} 

Что в этом не плохого? Является ли способ заявить, что мои указатели правильные?

+0

Вы не инициализировали указатели строк матрицы. –

ответ

2

Вы создаете массив указателей:

int **matrix = new int *[n] 

, но не инициализирует те, чтобы указать на что-либо; следовательно, ошибка сегрегации, когда вы пытаетесь разыменовать их. Если вы действительно должны жонглировать указатели, а затем выделить массив для каждого к точке:

for (int i = 0; i < n; ++i) { 
    matrix[i] = new int[n]; 
} 

и не забудьте удалить все из этих распределений, если вы заботитесь об утечках памяти.

Если это не упражнение в мазохизм, использовать стандартную библиотеку, чтобы сделать жизнь проще:

std::vector<std::vector<int>> matrix(n, std::vector<int>(n)); 

и вернуть std::vector<int>, а не int*, чтобы сохранить вызывающему абоненту хлопот жонглирование и удаления указателя.

+0

Я сделал это, а затем просто сплющил матрицу и вернул данные вектора, но это не получилось достаточно хорошо, так как я не мог найти существенный способ перебора их. Я исправил это, хотя я могу вернуться к ним. – T145

1

Вы только частично создаете матрицу. У вас есть int **matrix = new int *[n], который даст вам ваши строки, но вы определяете столбцы. Чтобы полностью инициализировать вам нужно использовать

int **matrix = new int *[n]; 
for (int i = 0; i < col_dimension; i++) 
    matrix[i] = new int[col_dimension]; 
1

Вы разыскиваете нулевые указатели. У вас есть 2-D массив:

int **matrix = new int *[n]; 

что вы ясно (неправильно - размер должен быть должен быть n * sizeof(*matrix)):

memset(matrix, 0, sizeof(matrix[0][0]) * square); 

а затем сразу же написать в:

for (int i = 1; i <= square; i++) { 
    matrix[row][col] = i; 
    .... 
} 

Но matrix[0] - NULL. Сначала вам нужно выделить все указатели!

for (int i = 0; i < n; ++i) { 
    matrix[i] = new int[whatever]; 
} 
+0

Будет ли '' 'быть' n'? – T145

+0

@ T145 Если он должен быть квадратным, то да. – Barry