Dynamic 2D array elements are not accessible several for loop - c

I've studied data structure and algorithm, and I got a problem with dynamic 2d array. Here is part of my code. The coding problem is the Knight's tour.
int iMove[8] = {-2, -1, 1, 2, 2, 1, -1, -2};
int jMove[8] = { 1, 2, 2, 1,-1, -2, -2, -1};
cell* cellList(int* i, int* j, int** board){
int k;
cell* temp;
int iTempNext; int jTempNext;
int maxSampleNum = 8;
int cnt = 0;
int val;
for(k = 0; k < maxSampleNum; k++){
iTempNext = (*i) + iMove[k];
jTempNext = (*j) + jMove[k];
//1. get list 0<=i<=7 && 0<=j<=7
if( (0 <= iTempNext && iTempNext <= 7) && (0 <= jTempNext && jTempNext <= 7)){
//2. get the 0 value cells
//val = canMove(iTempNext, jTempNext, board);
printf("%d %d\n", iTempNext, jTempNext);
if(board[iTempNext][jTempNext] == 0){
cell tempCell;
tempCell.row = iTempNext;
tempCell.col = jTempNext;
temp = (cell*)realloc(temp, sizeof(cell));
*(temp+cnt) = tempCell;
cnt++;
}
}
}
return temp;
}
int** board : 2d array and I allocated it dynamically and initialized all elements of this array to 0. I printed 2d array after initializing.
The problem is that after 2nd for loop, this program got segmentation fault on accessing 2d array. I cannot access 2d array elements during 3rd for loop.
Initializing Complete...
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
Enter the start position (i, j): 3 3
iTempNext jTempNext
1 4
2 5
4 5
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400b1c in cellList (i=0x7fffffffe5bc, j=0x7fffffffe5c0, board=0x603010) at main.c:144
144 if(board[iTempNext][jTempNext] == 0){
this is the result after using gdb. How can I solve this problem

This line:
temp = (cell*)realloc(temp, sizeof(cell));
invokes undefined behaviour since temp is not initialized. You should initialize it with, e.g., cell *temp = NULL; (understand that realloc can either take a NULL pointer in which case it is equivalent to malloc, or a previously malloced/calloced/realloced pointer).
And don't cast the return from malloc. This is C, not C++. Search this site for why casting the malloc return value is frowned upon in C.

Related

I cannot understand core dump cause of fgetc, how can I fix it?

I allocated matrix like this :
prevMatrix = (int**)malloc(sizeof(int) * arraySize[0]);
for (int i = 0; i < arraySize[0]; i++) {
prevMatrix[i] = (int*)malloc(sizeof(int) * arraySize[1]);
}
I checked arraySize[] has normal value. arraySize[0] means row, and arraySize[1] means column.
and I handed over the matrix like this :
void getInputMatrix(FILE* input, int column, int** matrix)
getInputMatrix(input, arraySize[1], prevMatrix);
and then function's body is this :
void getInputMatrix(FILE* input, int column, int** matrix) {
int i = 0, j = 0, c = 0;
while (!feof(input)) {
if (j == column) {
j = 0;
i++;
}
c = fgetc(input);
if (c != EOF && c != 32 && c != 10 && c != 13) {
matrix[i][j] = c - 48;
j++;
}
}
}
this is the example of matrix file:
1 0 0 0 0 0 0
0 1 0 1 0 0 0
0 1 0 0 1 1 0
0 1 1 1 0 0 0
0 0 0 0 1 0 0
0 1 0 0 0 1 0
1 0 1 1 0 0 0
0 1 0 0 0 0 1
It works very well in VS 2019, but it cause segmentation fault in Linux system(Ubuntu).
This program works well in Linux till the column is 6 or 7, but it occurs corrupted size vs. prev_size error or segmentation faultwhen the column overs that number.
Is it a problem of allocation? or fgetc()?
How can I fix it?
For starters, your first level allocation should be using the size of an int pointer rather than an int:
int **prevMatrix = malloc(sizeof(int*) * arraySize[0]);
If those types are different sizes, your original code could have a problem.
And, just as an aside, you should not cast the malloc return value in C, it can cause subtle problems.

How to send chunks of a big 2D array to function for processing

I have a 2D array storing image data using int. At this time it is 800x640 but that can change. I want to pass it to another function in 8x8 blocks for processing. I could actually just copy an 8x8 block of the array into a temporary variable and send that to the function and then copy result into another 800x640 array.
However, I want to the function to directly be able to access 8x8 blocks (which will be faster) if I give it the start xy coordinates within this 800x640 array. The problem is that using int** does not work. Also parameter declared as int[8][8] also does not compiled. What do I do? Right now I am writing the program in C++ but eventually shall have to write it in C as well.
You can give the pointer to the original image with other parameters to the function and access each element of your 8x8 area inside the function.
Let's say this is your original 800x640 image:
int img[640][800];
Declare your fuction as:
void work_on_roi(int* img, size_t img_width, size_t img_height, int roi_x, int roi_y, size_t roi_width, size_t roi_height)
ROI stands for region of interest, a widely used term in the field of image processing. In your case, if you want to access roi with (10,20) as its top-left index, you can call this function with arguments as:
work_on_roi(img, 800, 640, 10, 20, 8, 8)
Inside this function, accessing the (i,j) element in the roi would be:
(img + (roi_y + j) * img_width)[roi_x + i]
You can utilize roi_width and roi_height parameter to check for integrity:
// before accessing (i,j) element of roi
assert(i < roi_width);
assert(j < roi_height);
assert(roi_x + i < img_width);
assert(roi_y + j < img_height);
While the way you access the elements of the region will not change depending on how you have declared your array, the way you pass the array as a parameter will change depending on whether you have an actual 2D array or whether you have a pointer-to-pointer-to-type.
In the case of a true array declared similar to int array[X][Y]; (where X and Y are defined constants) you can pass a pointer to array of int [Y], (e.g. (*array)[Y]) as the parameter to your function.
In the case where array is will be converted to a pointer-to-pointer-to-type, when declared similar to int **array; or int (*array)[z]; where you allocate pointers and blocks of each row, or one single block, respectively, you simply pass a pointer-to-pointer-to-type (e.g. int **array)
Taking either case, you could change a region within the array with a simple function that iterates over the elements you wish to change. For example for the case where you have a 2D array as you specify, you could declare a function with logic similar to the following. (You could pass additional parameters as needed to effect whatever change you need)
enum { ROW = 10, COL = 10 }; /* constant definitions */
...
void chgregion (int (*a)[COL], int xs, int ys, int xn, int yn)
{
int xlim = xs + xn, /* xstart + xnumber_of_elements */
ylim = ys + yn; /* same for y */
if (xlim > ROW) xlim = ROW; /* protect array/block bounds */
if (ylim > COL) ylim = COL;
for (int i = xs; i < xlim; i++)
for (int j = ys; j < ylim; j++)
a[i][j] = 1; /* change element as required */
}
Above the a pointer to an array of COL elements is passed along with the x and y starting position within the array and the number of elements in the region, e.g. xn and yn. A simple check is done to limit the region size to remain within the array bounds or bounds of a block of memory. If your array is actually a pointer-to-pointer-to-type, just pass int **a instead and pass the dimensions of the block of memory as additional parameters.
You can put together a simple test as follows:
#include <stdio.h>
enum { ROW = 10, COL = 10 };
void chgregion (int (*a)[COL], int xs, int ys, int xn, int yn);
void prna (int (*a)[COL]);
int main (void) {
int a[ROW][COL] = {{0}};
prna (a);
chgregion (a, 2, 2, 6, 6);
putchar ('\n');
prna (a);
return 0;
}
void chgregion (int (*a)[COL], int xs, int ys, int xn, int yn)
{
int xlim = xs + xn,
ylim = ys + yn;
if (xlim > ROW) xlim = ROW;
if (ylim > COL) ylim = COL;
for (int i = xs; i < xlim; i++)
for (int j = ys; j < ylim; j++)
a[i][j] = 1;
}
void prna (int (*a)[COL])
{
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++)
printf ("%2d", a[i][j]);
putchar ('\n');
}
}
Example Use/Output
$ ./bin/array2d_region
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 1 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
Let me know if this is what you were intending, or if what you are doing differs in some way. For further help, please post a Minimal, Complete, and Verifiable example.

Clusters of a matrix(array)

So. I am working in C and I need some help. I have a matrix(array) (I do not now how to translate it right :D ) that has only 0 and 1 in it. For example, one could look like this:
1 1 0 0 0 0
1 1 0 1 0 0
1 0 0 0 0 1
0 0 1 1 0 1
0 0 1 0 1 1
Now. I need to extract from it the clusters that contain 1. Can you write me some ideas on how to approach this? I tried with a structure and a **pointer to it, with the structure containing 2 elements : x and y, x for x coordinate in the original matrix and y for the y coordinate in the matrix. Then, for each cluster, it would look like :
cluster[0][0].x = 0;
cluster[0][0].y = 0;
cluster[0][1].x = 1;
cluster[0][1].y = 0;
cluster[0][2].x = 0;
cluster[0][2].y = 1;
.. and so on. But I have some problems with the iteration( I have a 1000*1000 matrix) and I decided to ask you if you have any other ideas. Thanks.
EDIT: These are the clusters in this example:
1:
1 1 0 0 0 0
1 1 0 0 0 0
1 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
2:
0 0 0 0 0 0
0 0 0 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
3:
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 1 0 0
0 0 1 0 0 0
4:
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 1
0 0 0 0 0 1
0 0 0 0 1 1
EDIT2:
So. From that matrix of 1 and 0 and I nee to extract all groups of adjacent "1"'s. Adjacent means neighbouring on either up down left or right from it's position. As for the first cluster would be the one made up from those 5 "1"'s from the beginning of the matrix. Another cluster would be that that contains only one "1" on line 2 column 4. And I need somehow to store the x and y coordinate of each cluster somewhere, as I need to use them later on.
For string the data, just an array
char map[1000][1000]
that'll use 1 megabyte of memory, which is not a lot these days.
An algorithm as I see it is
find a 1 in the matrix,
do a flood-fill on it (eg changing 1 to 2 or to 0)
then continue searhcing for a 1 in the matrix.
return the number of fills needed to convert all the 1s.
Flood fill is a well known algorithm, you should be able to find a suitable example, or possibly use a graphics library.
A simple implemention
Use the backtracking to get all clusters, let's start from (0,0) as an example, we first check if (0,0) is 1, if so, check its neighbors one by one. If one of the neighbors is 1, move there and check in the same way. this process doesn't stop until the position's four direction neighbors are all 0 or visited.
To record the position we visited, we need a flag map which has the same size as origin array.
Besides, to draw each cluster, during the backtracking, we record each postion at the same time, I choose a set of list to save all positions in a cluster.
here is all code, including test case you post
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#define MAX_COL 6
#define MAX_ROW 5
#define MAX_SIZE (MAX_COL * MAX_ROW)
int a[5][6] = {
1, 1, 0, 0, 0, 0,
1, 1, 0, 1, 0, 0,
1, 0, 0, 0, 0, 1,
0, 0, 1, 1, 0, 1,
0, 0, 1, 0, 1, 1,
};
int dir_x[4] = {0, 1, 0, -1};
int dir_y[4] = {1, 0, -1, 0};
struct point {
int x;
int y;
};
struct node {
struct point pos;
struct node *next;
};
struct node* cluster_set[MAX_SIZE];
int cluster_set_index = 0;
int is_inside(int height, int width, int i, int j)
{
if (0 <= j && j < width && i >= 0 && i < height)
return 1;
return 0;
}
int cluster_check(int (*matrix)[MAX_COL], int height, int width, int row, int col, int (*flag_matrix)[MAX_COL], struct node* head)
{
int i, tmp_x, tmp_y;
flag_matrix[row][col] = 1;
for (i = 0; i < 4; i++)
{
tmp_x = row + dir_x[i];
tmp_y = col + dir_y[i];
if (is_inside(height, width, tmp_x, tmp_y) && matrix[tmp_x][tmp_y] && !flag_matrix[tmp_x][tmp_y]) {
flag_matrix[tmp_x][tmp_y] = 1;
struct node *new_node = (struct node*)malloc(sizeof(struct node));
assert(new_node != NULL);
new_node -> pos.x = tmp_x;
new_node -> pos.y = tmp_y;
new_node -> next = NULL;
head -> next = new_node;
cluster_check(matrix, height, width, tmp_x, tmp_y, flag_matrix, new_node);
}
}
}
int cluster_count(int (*matrix)[MAX_COL], int height, int width)
{
int count = 0, i, j;
int flag_matrix[MAX_ROW][MAX_COL] = {0};
for (i = 0; i < height; i++)
for (j = 0; j < width; j++)
{
if (matrix[i][j] && !flag_matrix[i][j]) {
count++;
struct node *new_node = (struct node*)malloc(sizeof(struct node));
assert(new_node != NULL);
new_node -> pos.x = i;
new_node -> pos.y = j;
new_node -> next = NULL;
cluster_set[cluster_set_index++] = new_node;
cluster_check(matrix, height, width, i, j, flag_matrix, new_node);
}
}
return count;
}
void print_cluster(int (*map)[MAX_COL], int row, int col)
{
int i, j;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
printf("%2d ", map[i][j]);
printf("\n");
}
printf("\n");
}
int main()
{
printf("total clusters: %d\n", cluster_count(a, 5, 6));
int i, cluster_map[MAX_ROW][MAX_COL] = {0};
struct node *tmp;
for (i = 0; i < cluster_set_index; i++)
{
tmp = cluster_set[i];
while (tmp != NULL) {
printf("(%d, %d)", tmp->pos.x, tmp->pos.y);
cluster_map[tmp->pos.x][tmp->pos.y] = 1;
tmp = tmp -> next;
}
printf("\n");
print_cluster(cluster_map, MAX_ROW, MAX_COL);
memset(cluster_map, 0x00, sizeof(int)*MAX_ROW*MAX_COL);
}
}
and here is the running results, just ignore the infomation you don't need
total clusters: 4
(0, 0)(0, 1)(1, 1)(1, 0)(2, 0)
1 1 0 0 0 0
1 1 0 0 0 0
1 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
(1, 3)
0 0 0 0 0 0
0 0 0 1 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
(2, 5)(3, 5)(4, 5)(4, 4)
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 1
0 0 0 0 0 1
0 0 0 0 1 1
(3, 2)(4, 2)
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 1 0 0 0
0 0 1 0 0 0

Segfault while allotting 2D array using double dimensional pointer

I'm currently working on a codechef practice problem http://www.codechef.com/problems/STEPUP#
I'm trying to set up a 2D array using pointers to accept the data and enter in into the 2D array as i receive it using scanf.
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char **argv)
{
int m,n,i,k,j;
int ex;
scanf("%d",&ex);
for(i=0;i<ex;i++)
{
int **edgegraph=NULL,temp1,temp2;
scanf("%d %d",&n,&m);
edgegraph=malloc(m*sizeof(int));
for(k=0;k<m;k++)
{
*(edgegraph+k)=malloc(m*sizeof(int));
if(!*(edgegraph+k))
exit(0);
}
for(k=0;k<m;k++)
{
scanf("%d %d",&temp1,&temp2);
*(*(edgegraph+m*temp1)+temp2)=1;
}
for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
printf("%d ",*(*(edgegraph+m*i)+j));
printf("\n");
}
}
}
The error i get is
(gdb) run
Starting program: /home/vishwa/codechef/valid
2
2 2
1 2
Program received signal SIGSEGV, Segmentation fault.
0x000000000040079d in main (argc=1, argv=0x7fffffffded8) at validedge.c:24
24 *(*(edgegraph+m*temp1)+temp2)=1;
(gdb) quit
What I intend to do is create an m*m matrix, set all valid edges to 1 and then sort in ascending order of number of edges. I'm unsure if this will solve the problem, but would like to know where I'm messing up.
You malloc the wrong number of bytes: edgegraph=malloc(m*sizeof(int)); should have malloc(m * sizeof(int *)); . To avoid this sort of error you can use the following pattern:
ptr = malloc( N * sizeof *ptr );
which always allocates N of whatever ptr is a pointer to.
Next, the syntax x[y] is much simpler to read than *(x+y) especially when the expressions get complicated. Using that syntax would have avoided the mistake dconman points outs. You seem to have put an extra m * into your calculation where it is not required.
Also you mix up m and n later in your code. To avoid this sort of error, use more descriptive variable names.
So a fixed version of your allocation code could look like:
if ( 2 != scanf("%d %d",&num_edges, &num_vertices) )
exit(EXIT_FAILURE);
edgegraph = malloc( num_vertices * sizeof *edgegraph );
for (int vertex = 0; vertex < num_vertices; ++vertex)
{
edgegraph[vertex] = malloc( num_vertices * sizeof **edgegraph );
if ( edgegraph[vertex] == NULL )
exit(EXIT_FAILURE);
}
Note that it is possible to replace that malloc series with a single allocation:
int (*edgegraph)[num_vertices] = malloc( num_vertices * sizeof *edgegraph );
Moving onto your code to read edges. You wrote for(k=0;k<m;k++) however I think you meant n there. Using more descriptive variable names and the x[y] syntax:
for(int edge = 0; edge < num_edges; ++edge)
{
if ( 2 != scanf("%d %d",&temp1,&temp2) )
exit(EXIT_FAILURE);
if ( temp1 < 0 || temp1 >= num_vertices || temp2 < 0 || temp2 >= num_vertices )
exit(EXIT_FAILURE); // maybe display an error message
edgegraph[temp1][temp2] = 1;
edgegraph[temp2][temp1] = 1; // add this if undirected graph!
}
Now the final loop, for(i=0;i<m;i++). You have used the same variable i as control variable for this loop and for your outer loop. To avoid this sort of error, use scoped control variables:
for (int i = 0; i < num_edges; ++i)
Finally you will need to free the memory you malloc'd at the end of each time around the outer loop.
You are so close: lose the m* in your expressions to access an array element. Remember, you set up your 2d array as an array of rows, each with its own pointer (you allocated each independently).
*(*(edgegraph+m*temp1)+temp2)=1;
should be
*(*(edgegraph+temp1)+temp2)=1;
And the same change where you do that later in your code.
Is there a reason you are not using array indices?
EDIT
here is my input
2
10
10
4 3
4 9
7 3
3 7
4 3
4 5
7 4
3 5
9 0
5 2
And I got this output
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 1 0 0
0 0 0 1 0 1 0 0 0 1
0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0

Pass 2D array by reference

I want to be able to pass a 2D array to a function, and have it directly change the array in main, so pass by reference. When I try to compile, I get error: expected expression before { in the switch cases. (boardSize=10, but that is not known at compilation time)
void fillBoard(int **, int);
int main() {
int **board = malloc(sizeof(int *) * boardSize);
fillBoard(board, boardSize);
}
void fillBoard(int **board) {
int i, *row = malloc(sizeof(int) * boardSize);
for (i=0; i<boardSize; i++) {
board[i] = malloc(sizeof(int) * boardSize);
switch(i) {
case 1: row = {1,0,1,0,1,1,0,0,1,0}; break;
default: row = {0,0,0,0,0,0,0,0,0,0}; break;
}
board[i] = row;
}
}
There a many different ways to do this. The key is to keep track of what you are addressing where. You can use a single or double pointer to pass and fill board, it all depends on how you want to keep track of the elements. (while the 2-dimensional array, provides a convenience in referencing elements, all values are sequential in memory, and can be accessed with a 1-dimensional reference and offset).
There is one important suggestion when allocating memory for numeric arrays. You must always initialize all elements of the array to protect against attempting to access or dereference an uninitialized value (Undefined behavior). The simple way to do this is to allocate with calloc instead of malloc. calloc allocates and initializes all values to zero (NULL).
Also be aware of the need to track the memory you allocate over the life of your program and free the memory when you no longer need it. This will prevent memory leaks from developing. In a short bit of code like the following, the memory is freed when the program exits. If this were part of some larger code, you would need to free board and board2 when there data was no longer needed.
An example using your original array would be:
#include <stdio.h>
#include <stdlib.h>
#define boardSize 10
void fillBoard_p (int *a);
void fillBoard_p2p (int **a);
int main() {
int i = 0;
int j = 0;
/* declaring board as an integer pointer */
int *board = calloc (boardSize * boardSize, sizeof (*board));
/* declaring board as a pointer to pointer */
int **board2 = calloc (boardSize, sizeof (*board2));
for (i = 0; i < boardSize; i++) {
board2[i] = calloc (boardSize, sizeof (**board2));
}
fillBoard_p (board);
fillBoard_p2p (board2);
printf ("\nboard as an integer pointer:\n");
for (i = 0; i < boardSize * boardSize; i++) {
if (i % boardSize == 0)
printf ("\n %d", board[i]);
else
printf (" %d", board[i]);
}
printf ("\n");
printf ("\nboard2 as an pointer to integer pointer:\n\n");
for (i = 0; i < boardSize; i++) {
for (j = 0; j < boardSize; j++) {
printf (" %d", board2[i][j]);
}
printf ("\n");
}
printf ("\n");
return 0;
}
void fillBoard_p(int *a) {
// 0=WHITE, 1=BLACK
int i = 0;
int j = 0;
int b [][boardSize] = {
{1,0,1,0,1,1,0,0,1,0},
{1,0,1,1,0,0,1,1,1,0},
{0,0,1,0,1,0,1,0,1,1},
{1,1,0,1,1,0,1,0,0,0},
{0,0,1,0,0,0,1,1,0,1},
{1,1,0,1,1,0,0,1,1,0},
{0,0,1,0,0,1,1,0,1,1},
{0,0,1,0,0,1,0,0,0,0},
{1,1,1,1,0,0,1,1,1,1},
{0,1,0,0,1,1,0,0,0,1}
};
for (i = 0; i < boardSize; i++)
for (j = 0; j < boardSize; j++)
a[i*boardSize+j] = b[i][j];
}
void fillBoard_p2p (int **a) {
// 0=WHITE, 1=BLACK
int i = 0;
int j = 0;
int b [][boardSize] = {
{1,0,1,0,1,1,0,0,1,0},
{1,0,1,1,0,0,1,1,1,0},
{0,0,1,0,1,0,1,0,1,1},
{1,1,0,1,1,0,1,0,0,0},
{0,0,1,0,0,0,1,1,0,1},
{1,1,0,1,1,0,0,1,1,0},
{0,0,1,0,0,1,1,0,1,1},
{0,0,1,0,0,1,0,0,0,0},
{1,1,1,1,0,0,1,1,1,1},
{0,1,0,0,1,1,0,0,0,1}
};
for (i = 0; i < boardSize; i++)
for (j = 0; j < boardSize; j++)
a[i][j] = b[i][j];
}
output:
$ ./bin/fillboard
board as an integer pointer:
1 0 1 0 1 1 0 0 1 0
1 0 1 1 0 0 1 1 1 0
0 0 1 0 1 0 1 0 1 1
1 1 0 1 1 0 1 0 0 0
0 0 1 0 0 0 1 1 0 1
1 1 0 1 1 0 0 1 1 0
0 0 1 0 0 1 1 0 1 1
0 0 1 0 0 1 0 0 0 0
1 1 1 1 0 0 1 1 1 1
0 1 0 0 1 1 0 0 0 1
board2 as an pointer to integer pointer:
1 0 1 0 1 1 0 0 1 0
1 0 1 1 0 0 1 1 1 0
0 0 1 0 1 0 1 0 1 1
1 1 0 1 1 0 1 0 0 0
0 0 1 0 0 0 1 1 0 1
1 1 0 1 1 0 0 1 1 0
0 0 1 0 0 1 1 0 1 1
0 0 1 0 0 1 0 0 0 0
1 1 1 1 0 0 1 1 1 1
0 1 0 0 1 1 0 0 0 1
Additionally, since a 2-D array is stored sequentially in memory, you can take advantage of that fact and make use of memcpy (in string.h) to fill the array passed to your function. This can reduce your function to:
void fillBoard_mc (int *a) {
// 0=WHITE, 1=BLACK
int b [][boardSize] = {
{1,0,1,0,1,1,0,0,1,0},
{1,0,1,1,0,0,1,1,1,0},
{0,0,1,0,1,0,1,0,1,1},
{1,1,0,1,1,0,1,0,0,0},
{0,0,1,0,0,0,1,1,0,1},
{1,1,0,1,1,0,0,1,1,0},
{0,0,1,0,0,1,1,0,1,1},
{0,0,1,0,0,1,0,0,0,0},
{1,1,1,1,0,0,1,1,1,1},
{0,1,0,0,1,1,0,0,0,1}
};
memcpy (a, b, boardSize * boardSize * sizeof (int));
}
Were it not for the particularity of the compiler and pointer decay, you could simply use a statically declared array, such as:
int board[boardSize][boardSize] = {{0}};
passing the address of the array to your function (becoming a 3-star programmer):
fillBoard (&board);
with a function similar to:
void fillBoard (int *a[][boardSize]) {
// 0=WHITE, 1=BLACK
int b [][boardSize] = {
{1,0,1,0,1,1,0,0,1,0},
{1,0,1,1,0,0,1,1,1,0},
{0,0,1,0,1,0,1,0,1,1},
{1,1,0,1,1,0,1,0,0,0},
{0,0,1,0,0,0,1,1,0,1},
{1,1,0,1,1,0,0,1,1,0},
{0,0,1,0,0,1,1,0,1,1},
{0,0,1,0,0,1,0,0,0,0},A
{1,1,1,1,0,0,1,1,1,1},
{0,1,0,0,1,1,0,0,0,1}
};
memcpy (a, b, boardSize * boardSize * sizeof (int));
}
Due to pointer decay (board[10][10] => board[*][10]), you will receive an incompatible pointer type warning, despite the function successfully copying the memory as intended. Code that does not compile without warning, should not be relied on in practice.

Resources