указатели — ошибка сегментации C ++ при передаче значений адреса между функциями

Я пытаюсь написать простой алгоритм C ++ для решения судоку. Я пытаюсь передать значения адреса между различными функциями, но я получаю ошибку сегментации во время выполнения. (Излишне говорить, что я не совсем опытный :))

Коду удается передать адрес [0] в функцию main, и я могу читать значения, используя указатели внутри main. Когда я пытаюсь передать адрес для решения функции, это дает ошибку сегментации.

(Также как дополнительный вопрос, я могу правильно прочитать значения в основном, используя cout << * (a + 5) и т. д. правильно (закомментировано в основном), но когда я пытаюсь распечатать все 81 значение, сохраненное с помощью цикла for, он выдает бессмысленные значения (опять же, закомментировано в коде). Код работает с литералами, такими как * (a + 3) или a [3], но не работает, когда int вовлекается для (int i, что угодно) cout << * (А + я);)

#include <iostream>
using namespace std;

int * get_input();
void solve(int *);

int main()
{
int * a;
a = get_input();
//cout << *a << " " << *(a+1) << " " << *(a+2) << " " << *(a+3) << " " << *(a+4);
//for (int i = 0 ; i < 81 ; i++) {if (i%9 == 0) cout << "\n"; cout << a[i] << " ";}
solve(a);
return(0);
}

int * get_input ()
{
int a[81];
getinput:
for (int i = 0 ; i < 81 ; i++)  {a[i] = 0;}
for (int i = 0 ; i < 81 ; i++)  {cin >> a[i];}
print:
for (int i = 0 ; i < 81 ; i++)
{
if (i%27 == 0){cout << "\n";}
if (i%9 == 0) {cout << "\n";}
if (i%3 == 0) {cout << "  " << a[i];}
if (i%3 != 0) {cout << a[i];}
}
cout << "\n\nCheck:\n1- Fix\n2- Reset\n3- Confirm\n\n";
int check = 0;
cin >> check;
if (check == 1)
{
int input[3] = {-1, -1, -1};
while (true)
{
cin >> input[0] >> input[1] >> input [2];
if (input[1] == 0) goto print;
a[(input[2]-1)+((input[1]-1)*9)] = input[0];
}
}
if (check == 2) goto getinput;
if (check == 3) return a;
}

void solve(int * a)
{
bool matrix[9][9][9];
for (int i = 0 ; i < 81 ; i++) {for (int j = 0 ; j < 9 ; j++) {matrix[(i-i%9)/9][i%9][j] = true;}}
for (int i = 0 ; i < 81 ; i++)
{
if (a[i] == 0) continue;
else
{
for (int j = 0 ; j < 9 ; i++)
{
matrix[(i-i%9)/9][j][a[i]] = false;
matrix[j][i%9][a[i]] = false;
matrix[((i-i%9)/9)-((i-i%9)/9)%3+j%3][i%9-(i%9)%3+(j-j%3)/3][a[i]] = false;
}
}
}
for (int i = 0 ; i < 9 ; i++)
{
for (int j = 0 ; j < 9 ; j++)
{
cout << matrix[i][j][1] << " ";
}
cout << "\n";
}
}

0

Решение

Сделать a массив в вашем get_input() функция static:

int a[81];

должно быть

static int a[81];

Это работает, потому что static Ключевое слово гарантирует, что выделенный блок памяти (массив a ) останется выделенным после возврата функции. Обычно это «потому что я еще не закончил с этим» (например, вы можете подсчитать, сколько раз ваша функция вызывается таким образом), но это также может, на законных основаниях, использоваться для гарантии того, что возвращаемое значение функции переживает конец функции.

Маргинально лучше было бы объявить массив на main уровень и передать указатель на него в get_input() а также solve() функции. Таким образом, вы явно указываете в коде, что массив будет «жить в течение всей программы» — и это обычно хорошая практика.

2

Другие решения

Вы возвращаете адрес локальной переменной в getInput(массив a). Я бы посоветовал передать массив в качестве аргумента этой функции. Другой вариант — динамически распределить массив, а затем позаботиться о его освобождении до завершения программы.

3

int a[81];

Это локальное распределение памяти, и оно освобождается, когда ваша функция get_input возвращается.

Использовать указатель int* a, а также malloc функция для динамического выделения памяти!

Команда malloc может выглядеть следующим образом (если я хорошо помню):

int *a = (int *) malloc(sizeof(int)*81);
1

Ваша проблема в том, что вы возвращаете указатель на локально объявленную переменную. Не делай этого. Вы должны либо передать переменную в качестве параметра (например, get_input (int [] arr, int length) `, либо выделить новую память в куче для вашего массива. Самый простой — первый, последний может привести к неприятностям, так как вы придется управлять вашей памятью или вы получите утечки памяти.

Зачем тебе это нужно? Когда вы объявляете [] в get_input он выделяет место для этой переменной в стеке. Стек — это длинный непрерывный блок памяти, который используется для хранения параметров функции, ее локальных переменных и адреса программы, которая вызывает текущую функцию. Когда функция возвращается, вся эта память возвращается для использования при следующем вызове функции. То есть когда solve называется он начинает перезаписывать память в стеке, который ранее использовался get_input,

Вам очень повезло, что вы получили ошибку сегментации, поскольку иногда программы могут продолжать работать, даже если их данные полностью повреждены.

В итоге: объявите ваш массив в главной функции и передайте его get_input оперировать.

0
По вопросам рекламы [email protected]