Getting a SIGSEGV error in my C program - c

This is my code for the problem.
I used a dynamic programming approach, and my answer is coming out to be correct. But I am getting a Runtime Error of SIGSEGV, may be because of array index and I am unable to figure out how and where?
If you can figure out what and where is the problem, please let me know.
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
int dynp(int i, int j);
int v[] = {-1, 0, 1, 0};
int h[] = {0, 1, 0, -1};
int ROW, COL;
#define INF 1000000
int minOfTwo(int one, int two){
if (one<two) {
return one;
}else{
return two;
}
}
int matrix[190][190];
int dp[190][190];
int main(int argc, const char * argv[]) {
int t;
scanf("%d", &t);
int i,j;
char s[190];
while (t--) {
scanf("%d %d", &ROW, &COL);
for (i = 0; i<ROW; i++) {
scanf("%s", s);
for (j = 0; j<COL; j++) {
matrix[i][j] = s[j] - 48;
dp[i][j] = INF;
}
}
for (i = 0; i<ROW; i++) {
for (j = 0; j<COL; j++) {
if (dp[i][j] == INF) {
if (matrix[i][j] == 1) {
dp[i][j] = 0;
}
else{
dp[i][j] = dynp(i, j);
}
}
}
}
for (i = 0; i<ROW; i++) {
for (j = 0; j<COL; j++) {
printf("%d ", dp[i][j]);
}
printf("\n");
}
}
return 0;
}
int dynp(int i, int j)
{
if (dp[i][j] != INF) {
return dp[i][j];
}
else{
if (matrix[i][j] == 1) {
dp[i][j] = 0;
return dp[i][j];
}
else{
int k;
for (k = 0; k<4; k++) {
int newi = i + v[k], newj = j + h[k];
if (newi < ROW && newj < COL && newi>=0 && newj>=0) {
dp[i][j] = minOfTwo(dp[i][j], 1 + dynp(newi, newj));
}
}
return dp[i][j];
}
}
}

At the first look, in your code,
scanf("%s", s);
for (j = 0; j<COL; j++) {
matrix[i][j] = s[j] - 48;
looks problematic. With the length of s lesser than the value of COL and s being an automatic local variable not initialized explicitly, you'll be accessing allocated but uninitialized memory location.
You should change the looping condition to something like
scanf("%189s", s); //to avoid overflow
int len = strlen(s);
for (j = 0; (j<COL) && (j < len); j++, len--) {
matrix[i][j] = s[j] - 48;

Related

What is the difference between Array[n] ; and Array[ ]={ };

#include <stdio.h>
int main() {
int n, i, j, k, l;
int temp;
printf("Enter how many element on the array : ");
scanf("%d", &n);
int arr1[100] = {};
for (i = 0; i < n; i++) {
scanf("%d", &arr1[i]);
}
for (j = 0; j < n; j++) {
for (k = j + 1; k < n; k++) {
if (arr1[j] > arr1[k]) {
temp = arr1[j];
arr1[j] = arr1[k];
arr1[k] = temp;
}
}
}
for (i = 0; i < n; i++) {
printf("%d \t", arr1[i]);
}
}
My code for sorting an array in ascending order works properly. And it doesn't have any error but when I am changed the array size then the code doesn't work properly and has an error called stack smashing detected. What causes this problem?
#include <stdio.h>
int main() {
int n, i, j, k, l;
int temp;
printf("Enter how many element on the array : ");
scanf("%d", &n);
int arr1[] = {};
for (i = 0; i < n; i++) {
scanf("%d", &arr1[i]);
}
for (j = 0; j < n; j++) {
for (k = j + 1; k < n; k++) {
if (arr1[j] > arr1[k]) {
temp = arr1[j];
arr1[j] = arr1[k];
arr1[k] = temp;
}
}
}
for (i = 0; i < n; i++) {
printf("%d \t", arr1[i]);
}
}
Neither int arr1[100] = {}; nor int arr1[] = {}; is valid C code.
The program compiles because your compiler implements GNU extensions that allow empty initializers and zero length arrays.
The reason your program no longer works when you remove the length 100 is the array becomes too short for the elements you try and store into it.
You probably meant to write int arr1[n] = {}; which does not compile because VLAs (variable sized arrays) cannot have an initializer.
Here is a modified version:
#include <stdio.h>
int main() {
int n, i, j, k, l;
printf("Enter how many element on the array : ");
if (scanf("%d", &n) != 1 || n <= 0) {
fprintf(stderr, "invalid size\n");
return 1;
}
int arr1[n];
for (i = 0; i < n; i++) {
if (scanf("%d", &arr1[i]) != 1) {
fprintf(stderr, "invalid input\n");
return 1;
}
}
for (j = 0; j < n; j++) {
for (k = j + 1; k < n; k++) {
if (arr1[j] > arr1[k]) {
int temp = arr1[j];
arr1[j] = arr1[k];
arr1[k] = temp;
}
}
}
for (i = 0; i < n; i++) {
printf("%d%c", arr1[i], "\t\n"[i == n - 1]);
}
return 0;
}

Code not running fully in VsCode but working in online compilers

This is the code i am talking about. It checks if a matrix is sparse or not . If it is then it changes it to sparse form and transposes it. When I run it with Vscode it runs and displays till it is sparse matrix but doesn't show its sparse form and transpose form but on online compiler it runs successfully till the end.
#include <stdio.h>
int checksparse();
int changematrix();
int main()
{
int a[100][100];
int i, j, r, c;
printf("Enter number of rows and columns in the matrix\n");
scanf("%d%d", &r, &c);
printf("\nEnter the elements in the matrix");
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
printf("\na[%d][%d] = ", i, j);
scanf("%d", &a[i][j]);
}
}
int check = checksparse(a, r, c);
if (check == 1)
{
printf("\nIts a sparse matrix\n");
changematrix(a, r, c);
}
else if (check == 0)
{
printf("\nIts not a sparse matrix");
}
return 0;
}
int checksparse(int array[100][100], int r, int c)
{
int counter = 0, flag = 1;
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
if (array[i][j] == 0)
counter++;
}
}
if (counter > ((r * c) / 2))
{
return flag;
}
else
{
flag = 0;
return flag;
}
}
int changematrix(int array[100][100], int r, int c)
{
int b[100][100], temp, counter = 0;
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
if (array[i][j] != 0)
{
b[temp][0] = i;
b[temp][1] = j;
b[temp][2] = array[i][j];
temp++;
counter++;
}
}
}
printf("\nSparse Matrix : \n");
for (int i = 0; i < counter; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", b[i][j]);
printf("\t");
}
printf("\n");
}
printf("\nTranspose of Sparse Matrix : \n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < counter; j++)
{
printf("%d ", b[j][i]);
printf("\t");
}
printf("\n");
}
return 0;
}

How to find out the inverse of an NXN matrix in C

Hi everyone I made some changes in the code so that it's easy to understand, looks what I have so far, I kept the function's prototype at the beginning of the code and it works fine, but it just works fine just when I try a 2x2 matrix because if I try a 3x3, 4x4 or 6x6 matrix it does not works fine the determinant is not calculated right, I guess that's the problem the determinant but I don't know how to solve it. Here is the code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<math.h>
float determinant(int tam,float [][tam]);
void cofactor(int tam,float [][tam]);
void transpose(int tam,float [][tam],float [][tam]);
int validate(){
int val;
char *buf = (char *) malloc(10);
memset(buf,0,10);
while(fgets(buf, 10, stdin) != NULL ){
if(buf[0]!='\n') {
val = atoi(buf);
break;
}
}
free(buf);
return val;
}
float determinant(int tam, float matrix[][tam])
{
float s = 1, det = 0, b[tam][tam];
int i, j, m, n, c;
if (tam == 1)
{
return (matrix[0][0]);
}
else
{
det = 0;
for (c = 0; c < tam; c++)
{
m = 0;
n = 0;
for (i = 0;i < tam; i++)
{
for (j = 0 ;j < tam; j++)
{
b[i][j] = 0;
if (i != 0 && j != c)
{
b[m][n] = matrix[i][j];
if (n < (tam - 2))
n++;
else
{
n = 0;
m++;
}
}
}
}
det = det + s * (matrix[0][c] * determinant( tam - 1,b));
s = -1 * s;
}
}
return (det);
}
void cofactor( int tam,float num[][tam])
{
float b[tam][tam], fac[tam][tam];
int p, q, m, n, i, j;
float x = 0;
for (q = 0;q < tam; q++)
{
for (p = 0;p < tam; p++)
{
m = 0;
n = 0;
for (i = 0;i < tam; i++)
{
for (j = 0;j < tam; j++)
{
if (i != q && j != p)
{
b[m][n] = num[i][j];
if (n < (tam - 2))
n++;
else
{
n = 0;
m++;
}
}
}
}
x = pow(-1, q + p) * determinant( tam - 1,b);
fac[p][q] = x;
}
}
transpose(tam,num, fac);
}
void transpose(int tam,float num[][tam], float fac[][tam])
{
int i, j;
float b[tam][tam], inverse[tam][tam], d;
for (i = 0;i < tam; i++)
{
for (j = 0;j < tam; j++)
{
b[i][j] = fac[j][i];
}
}
d = determinant(tam,num);
for (i = 0;i < tam; i++)
{
for (j = 0;j < tam; j++)
{
inverse[i][j] = b[i][j] / d;
}
}
printf("\n\n\nThe inverse of matrix is : \n");
for (i = 0;i < tam; i++)
{
for (j = 0;j < tam; j++)
{
printf("\t%f", inverse[i][j]);
}
printf("\n");
}
}
int verify_Size(int line){
if((line > 0) && (line <= 6))
{
return 1;
}
return 0;
}
int create_Matrix(int LINE){
int matrix[LINE][LINE];
float aux[LINE][LINE];
printf("\n\n\nPle:", (LINE * LINE));
printf("\n--------------------------------\n");
for(int i=0;i<LINE;i++)
{
for(int j=0;j<LINE;j++)
{
printf("Value[%d][%d]: ",i,j);
matrix[i][j] = validate();
}
}
printf("\n\nYour Bidimensional Matrix is:");
printf("\n--------------------------------\n");
for(int i=0;i < LINE;i++)
{
for(int j=0; j< LINE;j++)
{
printf("\t%2d",matrix[i][j]);
aux[i][j] = (float) matrix[i][j];
}
printf("\n");
}
float d = determinant(LINE,aux);
printf("\n\nDeterminante Main: %f \n",d);
if (d == 0)
printf("\nInverse of Entered Matrix is not possible\n");
else
cofactor(LINE,aux);
return 0;
}
int main(){
int flag,line;
do{
printf("Enter the order of the Matrix:\n");
printf("-------------------------------\n");
printf("Lines: ");
line = validate();
if(verify_Size(line)== 1)
{
create_Matrix(line);
}else{
printf("\nMatrix must to be till 6 X 6!\n");
flag = 0;
}
}while(flag != 1);
return 0;
}
It looks like you are finding the inverse matrix by Cramer's rule. While it works Ok for 2x2 or 3x3 matrix sizes, the hard part about implementing Cramer's rule generally is evaluating determinants. If you compute an NxN determinant following the definition, the computation is recursive and has factorial O(N!) computational complexity (Wikipedia).
I suggest switching to another algorithm. LUP factorization is fast and relatively simple, and Wikipedia has an example implementation.

Returning array in C, Sudoku Solver

So I'm creating a sudoku solver in C. Here's my full code as of now, I've mostly been using python and just got into C, I basically converted a lot of python functions to C to get this but I think it'll work:
#include <stdio.h>
#include <stdlib.h>
int is_empty();
int possible_v();
int solver();
int main(){
int s_array[9][9];
FILE * fpointer;
int i;
int j;
fpointer = fopen("sudoku001.txt", "r");
for (i=0; i<9; i++){
for(j = 0; j<9; j++){
fscanf(fpointer, "%d", &s_array[i][j]);
}
}
for (i=0; i<9; i++) {
if (i % 3 == 0) {
printf("------------------------------\n");
}
for (j = 0; j < 9; j++) {
printf(" %d ", s_array[i][j]);
if ((j + 1) % 3 == 0) {
printf("|");
}
}
printf("\n");
}
solver(s_array);
for (i=0; i<9; i++) {
if (i % 3 == 0) {
printf("------------------------------\n");
}
for (j = 0; j < 9; j++) {
printf(" %d ", s_array[i][j]);
if ((j + 1) % 3 == 0) {
printf("|");
}
}
printf("\n");
}
return 0;
}
int is_empty(int board[9][9]){
int i;
int j;
int is_empty= 0;
for (i=0; i<9; i++){
for(j = 0; j<9; j++){
if (board[i][j] == 0) {
is_empty = 1;
break;
}
}
if (is_empty == 1){
break;
}
}
return is_empty;
}
int possible_v(int board[9][9], int i, int j) {
int p_array[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
int x;
int y;
int temp;
for (x = 0; x < 9; x++) {
if (board[x][j] != 0) {
temp = board[x][j];
p_array[temp - 1] = temp;
}
}
for (y = 0; y < 9; y++) {
if (board[i][y] != 0) {
temp = board[i][y];
p_array[temp - 1] = temp;
}
}
int m;
int n;
int temp1;
int temp2;
if (i>= 0 && i <= 2) {
m = 0;
}
else if (i>= 3 && i<=5) {
m = 3;
}
else{
m = 6;
}
if (j>= 0 && j <= 2) {
n = 0;
}
else if (j>= 3 && j<=5) {
n = 3;
}
else{
n = 6;
}
temp1 = m;
temp2 = n;
for (temp1; temp1<temp1+3; temp1++){
for (temp2; temp2<temp2+3; temp2++){
if (board[temp1][temp2] != 0){
p_array[board[temp1][temp2]] = 1;
}
}
}
temp1 = 1;
for (temp1; temp1<10){
if (p_array[temp1] == 0){
p_array[temp1] = temp1;
}
else{
p_array[temp1] = 0;
}
}
return p_array;
}
int solver(int board[9][9]){
int i;
int j;
int x;
int y;
int empty_check;
int p_values;
int temp;
if (is_empty(board) == 0){
printf("Board Completed");
empty_check = 0;
return empty_check;
}
else{
for (x = 0; x < 9; x++){
for (y = 0; y< 9; y++){
if (board[x][y] == 0){
i = x;
j = y;
break;
}
}
}
p_values = possible_v(board, i, j);
for (temp = 1; temp <10; temp++){
if (p_values[temp] != 0){
board[i][j] = p_values[temp];
solver(board);
}
}
board[i][j] = 0;
}
}
My main issue when compiling is getting the last two functions work with each other.
Function 'solver' calls and binds function 'possible_v'. Possible_V returns an array which I need to solve the puzzle. How can I make this work? .
You have the array locally declared, hence it cannot be passed back since it is destroyed once the function is exited. The workaround to this is to dynamically declare the array using malloc int *parray = (int*)malloc(9*sizeof(int)); and using the return type int* instead of int. But do not forget to free the allocated memory, else you will just keep allocating new memory from heap for every call you make.
As a side note, your implementation of Sudoku solver is a bit complex, and there is no need to return an array. You need to pass only the board. Here is an implementation of Sudoku Solver. This works both for 9x9 and 6X6 boards.
Edit : As advised by David Rankin, I have converted the C++ code to C.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int n;
int issafe(int **board,int i,int j,int num){
for(int k=0;k<n;k++)
if(board[i][k] == num || board[k][j] == num)
return 0;
int cellx,celly;
if(n==6){
cellx = (i/2)*2;
celly = (j/3)*3;
for(int l=cellx;l<cellx+2;l++)
for(int m=celly;m<celly+3;m++)
if(board[l][m] == num){
return 0;
}
return 1;
}
int root = sqrt(n);
cellx = (i/(root))*root;
celly = (j/(root))*root;
for(int l=cellx;l<cellx+root;l++)
for(int m=celly;m<celly+root;m++)
if(board[l][m] == num)
return 0;
return 1;
}
int solve(int **board,int i,int j){
if(i == n)
return 1;
if(j == n){
return solve(board,i+1,0);
}
if(board[i][j] != 0)
return solve(board,i,j+1);
for(int k=1;k<n+1;k++)
if(issafe(board,i,j,k)){
board[i][j] = k;
if(solve(board,i,j+1))
return 1;
//backtrack
board[i][j] = 0;
}
return 0;
}
int main(){
do{
printf("Enter size of board(9 or 6): ");
scanf("%d",&n);
}while(n != 9 && n != 6);
int **board;
board = malloc(sizeof *board * n);
for(int i=0;i<n;i++)
board[i] = malloc(sizeof *board * n);
// input
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
scanf("%d",&board[i][j]);
if(solve(board,0,0))
for(int i=0;i<n;i++){
for(int j=0;j<n;j++)
printf("%d ",board[i][j]);
printf("\n");
}
return 0;
}

Unhandled exception in c

my code is compiled well, and executed. But I get this error after I enter the sortType value: "Unhandled exception at 0x52a56af2 (msvcr90d.dll) in ALINUR_CAGLAYAN_LAB6.exe: 0xC0000005: Access violation writing location 0x00000000."
Here's my code:
#include <stdio.h>
int sorting(int *liverpool8, int *besiktas0, int *hahaha);
void main()
{
int *numbers;
int length;
int sortType=0;
int i;
printf("Enter the length of array:");
scanf("%d",&length);
numbers = (int*)malloc(length*sizeof(int));
for (i = 0; i < length; ++i)
{
printf("%d. element: ", i+1);
scanf("%d", &numbers[i]);
}
printf("\nPlease select one of the following functions:\n1)Ascending order\n0)Descending order");
scanf("%d", sortType);
sorting(*numbers, &length, &sortType);
printf("The numbers arranged in the order as you entered are given below\n");
for (i = 0; i < length; ++i)
{
printf("%d\n", numbers[i]);
}
system("pause");
}
int sorting(int *numbers, int *length, int *sortType)
{
int j, i, a;
if(sortType == 1)
{
for (i = 0; i < length; ++i)
{
for (j = i + 1; j < length; ++j)
{
if (numbers[i] > numbers[j])
{
a = numbers[i];
numbers[i] = numbers[j];
numbers[j] = a;
}
}
}
}
else if(sortType == 0)
{
for (i = 0; i < length; ++i)
{
for (j = i + 1; j < length; ++j)
{
if (numbers[i] < numbers[j])
{
a = numbers[i];
numbers[i] = numbers[j];
numbers[j] = a;
}
}
}
return *numbers;
}
}
There are multiple errors in your code.
The header file for using malloc is not defines.
scanf needs to access addresses and not variables.
The array name decays to a pointer so using * for an array is double dereferencing
To access value in pointer you have to use *, the dereferencing pointer.
I have attached the corrected code.
#include <stdio.h>
#include <stdlib.h>
int sorting(int *liverpool8, int *besiktas0, int *hahaha);
void main()
{
int *numbers;
int length;
int sortType=0;
int i;
printf("Enter the length of array:");
scanf("%d",&length);
numbers = (int*)malloc(length*sizeof(int));
for (i = 0; i < length; ++i)
{
printf("%d. element: ", i+1);
scanf("%d", &numbers[i]);
}
printf("\nPlease select one of the following functions:\n1)Ascending order\n0)Descending order");
scanf("%d", &sortType);
sorting(numbers, &length, &sortType);
printf("The numbers arranged in the order as you entered are given below\n");
for (i = 0; i < length; ++i)
{
printf("%d\n", numbers[i]);
}
system("pause");
}
int sorting(int *numbers, int *length, int *sortType)
{
int j, i, a;
if(*sortType == 1)
{
for (i = 0; i < *length; ++i)
{
for (j = i + 1; j < *length; ++j)
{
if (numbers[i] > numbers[j])
{
a = numbers[i];
numbers[i] = numbers[j];
numbers[j] = a;
}
}
}
}
else if(sortType == 0)
{
for (i = 0; i < *length; ++i)
{
for (j = i + 1; j < *length; ++j)
{
if (numbers[i] < numbers[j])
{
a = numbers[i];
numbers[i] = numbers[j];
numbers[j] = a;
}
}
}
return *numbers;
}}

Resources