I am working with 2D arrays for the first time for a sudoku checker program; below is my code.
My program compiles without error, but when I run it, it gives me a segmentation fault.
It has been a while since I last coded, so I am unsure what I'm missing. I've also never had to deal with this error before.
My Code:
#include <stdio.h>
#include <stdlib.h>
int sudokuCheck();
int arrayMake();
#define SIZE 9
int main(){
int sudokAmount;
printf("Please Enter the amount of solutions to solve:\n");
scanf("%d",&sudokAmount);
arrayMake();
//sudokuCheck(sudokAmount);
return 0;
}
int arrayMake(){
int j;
int i;
int** sudoArr;
sudoArr = malloc(sizeof(int*) * SIZE * SIZE);
printf("Please Enter Sudoku Solutions(By rows)\n");
for(i = 0; i < SIZE; i++){
for(j=0; j < SIZE; j++){
scanf("%d\n", &sudoArr[i][j]);
}
}
for(i = 0; i < SIZE; i++){
for(j=0; j < SIZE; j++){
printf("%d \n", sudoArr[i][j]);
}
}
return 0;
}
First of all, you allocate memory for the matrix wrong way. Correct will be:
int** sudoArr = (int**)malloc(SIZE * sizeof(int*));
for (int index=0; index < SIZE; ++index)
{
sudoArr[index] = (int*)malloc(SIZE * sizeof(int));
}
Link to online compiler with correct version of your code: correct sources
Related
I want to initialise and print a 2-D array in two separate functions, but i don't really know if i am doing this correctly.
I wrote 2 functions: int** matrix_initialization(int n, int m) and int print_matrix(int n1, int n2, int **a);
In the first function i have to arguments: int n - the number of rows and int m - the number of cols. In this function i initialise a pointer to the pointer int **matrix = NULL; Then i allocate memory to it, and giving this 2-D array random values.
Is that okay that the type of the int** matrix_initialization(int n, int m) function is int ** ?
The second function is int print_matrix(int n1, int n2, int** a) and there are some problems, the main is that it is not working. I have three arguments int n1 - rows, int n2 - cols, int** a a pointer to the pointer. This function is to print matrix.
Here is my code:
#include <stdio.h>
#include <locale.h>
#include <stdlib.h>
#include <time.h>
int** matrix_initialization(int n, int m)
{
int** matrix = NULL;
matrix = (int**)malloc(n * sizeof(n));
if (matrix != NULL)
{
if (matrix != NULL)
{
for (int i = 0; i < m; i++)
{
*(matrix + i) = (int*)malloc(m * sizeof(m));
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
matrix[i][j] = rand() % 20 - 5;
}
}
}
}
return matrix;
}
int print_matrix(int n1, int n2, int** a)
{
for (int i = 0; i < n1; i++)
{
for (int j = 0; j < n2; j++)
{
printf("%d\t", a[i][j]);
}
printf("\n");
}
}
int main()
{
srand(time(NULL));
int N, M, **a;
scanf_s("%d %d", &N, &M);
a = matrix_initialization(N, M);
print_matrix(N, M, a);
}
There are many issues with this code.
Major:
You aren't using 2D arrays but arrays of pointers. That doesn't make the slightest sense for this application, you are just making your code more complex, error prone and slow for absolutely nothing gained. See Correctly allocating multi-dimensional arrays.
matrix = (int**)malloc(n * sizeof(n)); Both of your malloc calls are strange, n is just a size parameter (could as well be size_t) and not necessarily of the same type as the data. Which is a int* in this case, not an int. You should be allocating something like matrix = malloc(n * sizeof(*matrix))
The first for loop for (int i = 0; i < m; i++) is wrong, should be n.
You aren't freeing allocated memory.
Minor:
locale.h isn't needed for this program.
There's no actual need to initialize your pointer matrix to NULL if you are to assign to it on the next line. Also you have multiple redundant checks vs NULL.
*(matrix + i) is never the best way to access an array in C, it's just an obscure way of writing matrix[i]. Don't complicate things just for the heck of it.
Don't name parameters n and m in one function and then n1 n2 in another function. Don't complicate things just for the heck of it.
Avoid functions ending with _s unless you have specific reasons why you need to use them. They are non-portable. It's very likely that whoever told you to use it has no idea what they are talking about. Including no idea about the whole "bounds-checking interface" debacle in C11.
int main() is obsolete style, always use int main (void) (as opposed to C++).
Here is a rewrite with all problems fixed, using 2D arrays instead:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void* matrix_initialization (int n, int m)
{
int (*matrix)[m] = malloc( sizeof(int[n][m]) );
if (matrix != NULL)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
matrix[i][j] = rand() % 20 - 5;
}
}
}
return matrix;
}
void print_matrix (int n, int m, int a[n][m])
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
printf("%d\t", a[i][j]);
}
printf("\n");
}
}
int main (void)
{
srand(time(NULL));
int N, M;
scanf("%d %d", &N, &M);
int (*a)[M];
a = matrix_initialization(N, M);
print_matrix(N, M, a);
free(a);
}
You have two major problems:
The first is
malloc(n * sizeof(n))
which is the same as
malloc(n * sizeof(int))
And that makes no sense when you want to create an array of n pointers to int. On a 64-bit system it's unlikely that sizeof(int) == sizeof(int *).
It should be
malloc(n * sizeof(int*))
Or better yet
malloc(n * sizeof *matrix)
The second problem is your loop where you allocate the int arrays:
for (int i = 0; i < m; i++)
You have just created an array of n elements. Now you iterate over m elements? This will only work if n == m.
The correct loop should of course be
// Iterating over an array of n elements
for (int i = 0; i < n; i++)
You also have the same problem with the malloc call as mentioned above, but this time it just so happens to work because m is an int which is the right type and size.
On another few notes, in C you should not cast the result of malloc.
You never free any of the data you allocate, leading to memory leaks.
And instead of *(matrix + i) use matrix[i].
#include <stdio.h>
#include <locale.h>
#include <stdlib.h>
#include <time.h>
int** matrix_initialization(int n, int m)
{
int** matrix = NULL;
//matrix = (int**)malloc(n * sizeof(n));
matrix = (int**)malloc(n * sizeof(int *));
if (matrix != NULL)
{
for (int i = 0; i < n; i++)//here is n,not m
{
matrix[i] = (int*)malloc(m * sizeof(int));
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
matrix[i][j] = rand() % 20 - 5;
}
}
}
return matrix;
}
int print_matrix(int n1, int n2, int** a)
{
for (int i = 0; i < n1; i++)
{
for (int j = 0; j < n2; j++)
{
printf("%d\t", a[i][j]);
}
printf("\n");
}
return 0;
}
int main()
{
srand(time(NULL));
int N, M, **a,i;
scanf("%d %d", &N, &M);
a = matrix_initialization(N, M);
print_matrix(N, M, a);
//free all the memory
for (i = 0; i<N; i++) {
free(a[i]);
}
free(a);
return 0;
}
As suggested by a book of "Gottfried", I tried to input an array and display the contents of array in matrix form :
#include<stdio.h>
#define row 2
#define col 3
int main(){
int (*a)[col];
int i,j;
for(i=0;i<row;i++){
for(j=0;i<col;j++){
printf("Enter a(%d,%d)",i,j);
scanf("%d",(*(a+i)+j));
}
}
return 0;
}
I get the following output after inputting an element :
Segmentation fault (core dumped)
What is the problem in the code? Was it working in previous version of GCC so the writer wrote it down? What is the correct way to solve the problem with the same level of simplicity?
As it was pointed out in the comments it is not a 2D array, but a 1D array of pointers.
Also in the second for loop you accidently use i<col instead of j<col.
This will work
#include<stdio.h>
#define ROW 2
#define COL 3
int main(){
int a[ROW][COL];
int i, j;
for(i = 0; i < ROW; i++){
for(j = 0;j < COL; j++){
printf("Enter a(%d,%d)", i, j);
scanf("%d", (*(a + i ) + j));
}
}
return 0;
}
If you want to declare a as a pointer to an array of col ints, as it's done in this line
int (*a)[col];
Then you should also allocate (and ultimately free) the memory needed, before trying to use it.
a = malloc(sizeof(*a) * row);
if (!a)
exit(1);
// ...
free(a);
The posted code also have another issue in the nested loops
for (i = 0; i < row; i++) {
for (j = 0; i < col; j++) {
// ^^^^^^^ It should be 'j < col'
Hello I had to write a program (well still have) that would allocate memory in function for storing numbers that you have to input then print a matrix (rows and columns are the same size). Most importantly the program has to be written using pointers, local variables, functions and C 89 standard.
#include <stdio.h>
#include <stdlib.h>
void Matrix_Input(int *m, int ***Matrix);
void Matrix_Output(int m, int **Matrix);
int main()
{
int m;
int **Matrix;
int i;
Matrix_Input(&m, &Matrix);
Matrix_Output(m, Matrix);
for (i = 0; i < m; i++) /*free memory*/
free(*(Matrix+i));
free(Matrix);
return 0;
}
void Matrix_Input(int *m, int ***Matrix)
{
int i, j;
printf("Input number of rows/columns: \n");
scanf("%d", m);
*Matrix = malloc(*m* sizeof(int*)); /*allocate memory*/
for (i = 0; i < *m; i++)
*(*Matrix+i) = malloc(*m* sizeof(int));
printf("Input integers: \n");
for (i = 0; i < *m; i++)
for (j = 0; j < *m; j++)
scanf("%d", &((*Matrix)[i][j]));
}
void Matrix_Output(int m, int **Matrix)
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < m; j++)
printf("%5d", Matrix[i][j]);
printf("\n");
}
}
The program works fine, but I was asked not to use triple pointers here(for input function):
void Matrix_Input(int *m, int ***Matrix)
Teacher told me to use double pointers for input function just like I did for output like this:
void Matrix_Input(int *m, int **Matrix)
And this is where everything goes wrong since I only know how to allocate with triple pointers. I have to leave input as a separate function, can't put it in main.
Could someone help me out? Please.
Return your Matrix pointer instead. It's an output to the function, not a real input.
int** Matrix_Input(int* n)
I know this question is everywhere, but i cannot find a solution, and at this point i got pretty frustrated.
What I am trying to do is to create and use a static library. Got in the last point where i need to Build the solution, but i keep getting this error. I know the code has something, maybe more, MAYBE IS COMPLETE NONSENSE, but I can`t really see it after hours and hours trying to make it work. You know, "You cant see the forest because of the trees" W/e. Here are some screens.
#include <iostream>
#include <conio.h>
#include "matrice.h"
void din_alocation(int n, int m){
float **mat;
mat = (float**)calloc(n, sizeof(float*));
for (int i = 0; i < n; i++)
mat[i] = (float*)calloc(m, sizeof(float));
}
void read(float **mat, int n, int m){
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) {
printf("mat[%d][%d]= ", i, j); scanf_s("%f", &mat[i][j]);
}
}
void write(float **mat, int n, int m){
for (int i = 0; i < n; i++){
printf("\n");
for (int j = 0; j < m; j++)
printf("%.2f ", mat[i][j]);
}
}
void din_realocation(float **mat, int n){
for (int i = 0; i < n; i++)
free(mat[i]);
free(mat);
}
The error should be pretty clear. You don't initialize the variable mat anywhere in the main function.
One solution is for the din_alocation function to return the data it allocates, and then do
mat = din_alocation(x, y);
I have 2 simple functions, one function inputs in the the NxM array not including N+2 and M+2. So the original array must be surrounded by zeros and the other outputs the whole array. When the out function is called I have a very strange output:
But when I move the code to the main function everything is totally fine. I tried compiling this code in CodeBlocks and NetBeans.Behaviour is the same.
I don't know what's going on there. Can somebody explain?
.....
int main()
{
int array[N+2][M+2]={{0}};
local_in(N,M,array);
local_out(N,M,array);
return 0;
}
void local_in(int len, int len2,int arr[][len2])
{
int i;
int j;
for(i = 1; i <= len; i++)
for(j = 1; j <= len2; j++){
scanf("%d",&arr[i][j]);
}
}
void local_out(int len, int len2,int arr[][len2])
{
int i;
int j;
for(i = 0; i < len+2; i++){
for(j = 0; j < len2+2; j++)
printf("%d ",arr[i][j]);
printf("\n");
}
}
Your local_* functions pass the array as int arr[][len2]; but should use int arr[][len2+2] instead.
In general, the code should be much clearer if you passed the correct array dimensions around then implemented any policy on which items to read or write inside the local_* functions.