'How do you assign a multidimensional array of pointers to a multidimensional array of values in C?
I'm working on a Sudoku Solver, and I have to evaluate values in RealPuzzle (without changing them), and then decide whether or not the desired number can go somewhere (which requires a FakePuzzle with 1's and 0's based on whether a number can go in the slot or not). Needless to say it's a lot of looping, and pointers are required.
So I have a multidimensional array Puzzle1.Sudoku[Value][Set], which correctly organizes, assigns, and returns the actual values. Now I want to assign pointers to it, but I keep getting garbage data when I dereference them. As you can see, I have used a struct to pass everything from one function to another. Part of the struct is the actual values, another part is the pointers to those values.
Because it's a struct, I declared a typedef in a header file, which means I declared the pointers without initializing them. Here's how the struct is defined for your reference.
typedef struct puzzle
{
int Sudoku[9][9];
int * pSudoku;
struct Rows
{
int * pRowValues[9][9];
int RowNumber[9];
} Row;
struct Columns
{
int * pColumnValues[9][9];
int ColumnNumber[9];
} Column;
struct Boxes
{
int * pBoxValues[9][9];
int BoxNumber[9];
} Box;
} Puzzle;
If the Box section was the only one giving me problems, I'd blame the math in the brackets. But the Rows are also giving me garbage data, and it's just pPointer[x][y] = &thing[x][y].
Everything compiles/builds, runs, and debugs without an issue, it's just not working because my pointers return garbage. Can anyone let me know what I'm doing wrong, or what might cause me to get garbage data in this situation?
Edit:
Here's the full process. First the header file, which I've already posted in its entirety. Then is the Setup file, where I initialize the various parts of the struct including the Sudoku (as all 0's) and the pointers:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Setup.h"
Puzzle Setup()
{
/*
*************************
First, set up the problem
*************************
*/
Puzzle Puzzle1;
int NullMatrix[9][9] = {0};
int ThisIsHowCountingWorks[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int Set=0, Bump=0, Value=0;
memcpy(Puzzle1.Sudoku, NullMatrix, sizeof(Puzzle1.Sudoku));
memcpy(Puzzle1.Row.RowNumber, ThisIsHowCountingWorks, sizeof(Puzzle1.Row.RowNumber));
memcpy(Puzzle1.Column.ColumnNumber, ThisIsHowCountingWorks, sizeof(Puzzle1.Column.ColumnNumber));
memcpy(Puzzle1.Box.BoxNumber, ThisIsHowCountingWorks, sizeof(Puzzle1.Box.BoxNumber));
Puzzle1.pSudoku = &Puzzle1.Sudoku[0][0];
/*
************************************************
Define pointers for the values and the Structure
************************************************
*/
//Rows
for(Set=0; Set<9; Set++)
{
for(Value=0; Value<9; Value++)
{
Puzzle1.Row.pRowValues[Value][Set] = &Puzzle1.Sudoku[Value][Set];
}
}
//Columns
for(Set=0; Set<9; Set++)
{
for(Value=0; Value<9; Value++)
{
Puzzle1.Column.pColumnValues[Value][Set] = &Puzzle1.Sudoku[Set][Value];
}
}
//Boxes
for(Set=0; Set<3; Set++)
{
for(Bump=0; Bump<3; Bump++)
{
for(Value=0; Value<9; Value++)
{
if(Value<3)
{
Puzzle1.Box.pBoxValues[Value][Bump + 3*Set] = &Puzzle1.Sudoku[3*Bump + Value-0][0 + 3*Set];
}
else if(Value>=3&&Value<6)
{
Puzzle1.Box.pBoxValues[Value][Bump + 3*Set] = &Puzzle1.Sudoku[3*Bump + Value-3][1 + 3*Set];
}
else if(Value>=6)
{
Puzzle1.Box.pBoxValues[Value][Bump + 3*Set] = &Puzzle1.Sudoku[3*Bump + Value-6][2 + 3*Set];
}
}
}
}
return Puzzle1;
}
From there it goes to the main file, which immediately sends it to the Input, where the user sets the individual values and their locations in the full puzzle:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Setup.h"
/*
********************************************
In this bit, we get some info from the user
and then assign that cleverly to the puzzle.
********************************************
*/
Puzzle Input(Puzzle Puzzle1)
{
printf(
"\n"
"\n"
"*************************************\n"
"Welcome to the Super Sudoku Solver!!!\n"
" I am your host, Puzzle Pat!\n"
"*************************************\n"
"\n"
"\n"
"Before we begin, may I get your name?\n"
);
char name[50];
scanf(" %100s", &name[0]);
printf(
"\n------------------------------------------\n"
"Hello, %s!\n"
"It's good to see you!\n"
"\n"
"I would like you to enter the values\n"
"given in your Sudoku puzzle.\n"
"\n"
"Please give them to me in this format:\n"
"Row Number, Column Number, Value Number\n"
"\n"
"So for example, if there's a 3 on row 2,\n"
"column 5, you'd type in '2, 5, 3'\n"
"\n"
"Please enter the first entry:\n",
name
);
char spot1[10] = {0};
scanf(" %9[a-z | A-Z | 0-9/,.-]", &spot1[0]);
int assignment[3] = {0};
int alpha = spot1[0] - '0';
int beta = spot1[3] - '0';
int gamma = spot1[6] - '0';
assignment[0] = alpha - 1;
assignment[1] = beta - 1;
assignment[2] = gamma;
Puzzle1.Sudoku[assignment[1]][assignment[0]] = assignment[2];
char more[10] = {0};
printf(
"\n----------------------------------------------------------\n"
"Great! Are there any more entries you want to record?\n"
);
scanf(" %8s", &more[0]);
while(strcmp(more, "Yes") != 0&&strcmp(more, "yes") != 0&&strcmp(more, "Y") != 0&&strcmp(more, "y") != 0&&strcmp(more, "No") != 0&&strcmp(more, "no") != 0&&strcmp(more, "N") != 0&&strcmp(more, "n") != 0)
{
printf("\nPlease enter either a Yes or a No.\n");
scanf(" %8s", more);
}
int loop = 0;
while(strcmp(more, "Yes") == 0||strcmp(more, "yes") == 0||strcmp(more, "Y") == 0||strcmp(more, "y") == 0)
{
char Support[10][15] =
{
"Cool",
"Awesome",
"Nice",
"Alright",
"Sweet",
"Great",
"Excellent",
"Wonderful",
"Heck yeah",
"Gnarly",
};
printf(
"\n--------------------------------------------------------------------\n"
"Okay, add the next number the same way you did the last one.\n"
);
char spot2[10] = {0};
scanf(" %9[a-z | A-Z | 0-9/,.-]", &spot2[0]);
int assignment2[3] = {0};
int alpha2 = spot2[0] - '0';
int beta2 = spot2[3] - '0';
int gamma2 = spot2[6] - '0';
assignment2[0] = alpha2 - 1;
assignment2[1] = beta2 - 1;
assignment2[2] = gamma2;
Puzzle1.Sudoku[assignment2[1]][assignment2[0]] = assignment2[2];
printf(
"\n----------------------------------------------------------\n"
"%s! Are there any more entries you want to record?\n",
Support[loop]
);
scanf(" %8s", more);
while(strcmp(more, "Yes") != 0&&strcmp(more, "yes") != 0&&strcmp(more, "Y") != 0&&strcmp(more, "y") != 0&&strcmp(more, "No") != 0&&strcmp(more, "no") != 0&&strcmp(more, "N") != 0&&strcmp(more, "n") != 0)
{
printf("\nPlease enter either a Yes or a No.\n");
scanf(" %8s", more);
}
if(loop<9)
{
loop = loop + 1;
}
else
{
loop = 0;
}
}
return Puzzle1;
}
Then it goes back to main, and since I realized I was getting garbage data, I have main set to print the values of Sudoku and the values that the pointers point to:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Setup.h"
Puzzle Setup();
Puzzle Input(Puzzle);
Puzzle Calculate(Puzzle);
int Set=0, Bump=0, Value=0;
int main()
{
/*
********************
First, run the Setup
********************
*/
Puzzle Puzzle1 = Setup();
/*
*****************************************
Then get input about this specific puzzle
*****************************************
*/
Puzzle Puzzle2 = Input(Puzzle1);
//Rows
for(Set=0; Set<9; Set++)
{
for(Value=0; Value<9; Value++)
{
if(Value==3||Value==6)
{
printf("-------------\n");
}
if(Set==3||Set==6)
{
printf("|");
}
printf("%d ", Puzzle2.Sudoku[Value][Set]);
printf("%d\n", *(Puzzle2.Row.pRowValues[Value][Set]));
if(Set==8)
{
printf("\n");
}
}
}
printf("\n\n");
//Columns
for(Set=0; Set<9; Set++)
{
for(Value=0; Value<9; Value++)
{
if(Value==3||Value==6)
{
printf("-------------\n");
}
if(Set==3||Set==6)
{
printf("|");
}
printf("%d ", Puzzle2.Sudoku[Set][Value]);
printf("%d\n", *(Puzzle2.Column.pColumnValues[Value][Set]));
if(Set==8)
{
printf("\n");
}
}
}
printf("\n\n");
//Boxes
for(Set=0; Set<3; Set++)
{
for(Bump=0; Bump<3; Bump++)
{
for(Value=0; Value<9; Value++)
{
if(Value==3||Value==6)
{
printf("-------------\n");
}
if(Set==3||Set==6)
{
printf("|");
}
if(Value<3)
{
printf("%d ", Puzzle2.Sudoku[3*Bump + Value-0][0 + 3*Set]);
printf("%d\n", *(Puzzle2.Box.pBoxValues[Value][Bump + 3*Set]));
}
else if(Value>=3&&Value<6)
{
printf("%d ", Puzzle2.Sudoku[3*Bump + Value-3][1 + 3*Set]);
printf("%d\n", *(Puzzle2.Box.pBoxValues[Value][Bump + 3*Set]));
}
else if(Value>=6)
{
printf("%d ", Puzzle2.Sudoku[3*Bump + Value-6][2 + 3*Set]);
printf("%d\n", *(Puzzle2.Box.pBoxValues[Value][Bump + 3*Set]));
}
if(Set==8)
{
printf("\n");
}
}
}
}
/*
********************************************
After that, run Calculate to get the answers
********************************************
*/
printf(
"\n------------------------------------\n"
"Alright, leave the rest to me!\n\n"
);
Puzzle Puzzle3 = Calculate(Puzzle2);
/*
***************************
Finally, output the results
***************************
*/
int r=0, c=0;
for(r=0; r<9; r++)
{
for(c=0; c<9; c++)
{
if(Puzzle3.Sudoku[r][c]==0)
{
return 0;
}
else
{
continue;
}
}
}
printf("The solution is\n");
for(r=0; r<9; r++)
{
if(r==3||r==6)
{
printf("-------------\n");
}
for(c=0; c<9; c++)
{
if(c==3||c==6)
{
printf("|");
}
printf("%d", Puzzle3.Sudoku[c][r]);
if(c==8)
{
printf("\n");
}
}
}
return(0);
}
As you can probably tell, there's more to the program after this much, but I can't tell if those are working properly or not because my pointers don't work right when I print them. So I need to make sure I have everything before the Calculate section properly set up.
Finally I want to mention how the pointers are meant to be set up. I'm trying to do a [Value], [Set] system. So let's say I have a 3x3, initialized to
{(1, 2, 3), (4, 5, 6), (7, 8, 9)}
pRow[0-2][1] should return
(4, 5, 6)
pColumn[0-2][2] should return
(3, 6, 9)
and pBox[0-8][0] should return
(1, 2, 3, 4, 5, 6, 7, 8, 9)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
