Why am I getting segmentation fault [139]? - c

The title is pretty clear I think.
I am trying to create a program that calculates a 3x3 linear system using determinants, but I am getting a segmentation fault. Here is the code:
#include<stdio.h>
int determinant(int n, int m, int det[m][n])
{
int res;
res = det[0][0]*det[1][1] - det[0][1]*det[1][0];
return res;
}
int main(void)
{
int arr[3][4], det[2][2], i, j, D; //Dx1, Dx2, Dx3
for(i = 0; i < 3; i++)
{
printf("Eisagete tous suntelestes ths %dhs eksisoshs.", i+1);
scanf("%d %d %d %d", &arr[i][0], &arr[i][1], &arr[i][2], &arr[i][3]);
}
for(i = 0; i < 2; i++)
{
for(j = 0; j < 2; i++)
{
det[i][j] = arr[i+1][j+1];
}
}
D = arr[0][0]*determinant(2, 2, det);
for(i = 0; i < 2; i++)
{
for(j = 0; j < 2; i++)
{
det[i][j] = arr[i+1][j+((j == 1) ? 1 : 0)];
}
}
D -= arr[0][1]*determinant(2, 2, det);
for(i = 0; i < 2; i++)
{
for(j = 0; j < 2; i++)
{
det[i][j] = arr[i+1][j];
}
}
D += arr[0][2]*determinant(2, 2, det);
printf("%d\n", D);
}
I am getting the error right after completing the first for loop in main.

In the block:
for(i = 0; i < 2; i++)
{
for(j = 0; j < 2; i++)
{
det[i][j] = arr[i+1][j+1];
}
}
You increment i in both loops, and adding 1 more to it while reading from the array. So at arr[i+1] you are reading to far.
A segmentation fault basically means you are trying to read something you don't have access to.

You shoud never do what you're doing by passing static array sizes m and n as function argument:
int determinant(int n, int m, int det[m][n])
Check https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html for info

Related

Merge two 2d arrays into one 1d array in C

I have taken two 2d arrays but the output is very different from expected.It should merge two 2d arrays into one 1d array.I want to merge two arrays.Not add.Everywhere the information and examples are about merging two 1D arrays.Please help someone.I don't know where I am wrong.
#include <stdio.h>
void print(int a[][3],int m);
int main()
{
int array1[3][3];
int array2[3][3];
int arraySum[6][3];
int k = 0; //put into array;
int l = 10;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
array1[i][j] = ++k; //fill from 1 to 10
array2[i][j] = ++l; //fill from 11 - 19
}
}
/*merge arrays*/
for(int i = 0; i < 6; i++)
{
for(int j = 0; j < 3; j++)
{
(i < 3) ? arraySum[i][j] = array2[i][j] : arraySum[i][j] = array1[i-3][j];
//fill arraySum with array2 and append with array1.
//just so that arraySum does not have any order
}
}
printf("Arrays before sorting");
printf("Array 1: ");
print(array1,3);
printf("Array2: ");
print(array2,3);
printf("arraySum");
print(arraySum,6);
/* bubble sort*/
for(int i = 0; i < 6; i++)
{
for(int j = 0; j < 3; j++)
{
for(int k = i+1; k < 6; k++)
{
for(int m = 0; m < 3; m++)
{
if(arraySum[i][j] > arraySum[k][m])
{
//swap
int temp = arraySum[i][j];
arraySum[i][j] = arraySum[k][m];
arraySum[k][m] = temp;
}
}
}
}
}
printf("\n\n Merged Array after sorting");
print(arraySum,6);
return 0;
}
void print(int a[][3],int m)
{
for(int i = 0; i < m; i++)
{
for(int j = 0; j < 3; j++)
{
printf("%d" , a[i][j]);
}
}
}
I want to merge two arrays.Not add.Everywhere the information and examples are about merging two 1D arrays.Please help someone.I don't know where I am wrong.
Please try this code,To Merge two 2d arrays into one 1d array in C
#include <stdio.h>
void print(int a[][3],int m);
int main()
{
int array1[3][3];
int array2[3][3];
int arraySum[6][3];
int k = 0; //put into array;
int l = 10;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
array1[i][j] = ++k; //fill from 1 to 10
array2[i][j] = ++l; //fill from 11 - 19
}
}
/*merge arrays*/
for(int i = 0; i < 6; i++)
{
for(int j = 0; j < 3; j++)
{
(i < 3) ? (arraySum[i][j] = array2[i][j]) : (arraySum[i][j] = array1[i-3][j]);
//fill arraySum with array2 and append with array1.
//just so that arraySum does not have any order
}
}
printf("Arrays before sorting");
printf("Array 1: ");
print(array1,3);
printf("Array2: ");
print(array2,3);
printf("arraySum");
print(arraySum,6);
/* bubble sort*/
for(int i = 0; i < 6; i++)
{
for(int j = 0; j < 3; j++)
{
for(int k = i+1; k < 6; k++)
{
for(int m = 0; m < 3; m++)
{
if(arraySum[i][j] > arraySum[k][m])
{
//swap
int temp = arraySum[i][j];
arraySum[i][j] = arraySum[k][m];
arraySum[k][m] = temp;
}
}
}
}
}
printf("\n\n Merged Array after sorting");
print(arraySum,6);
return 0;
}
void print(int a[][3],int m)
{
for(int i = 0; i < m; i++)
{
for(int j = 0; j < 3; j++)
{
printf("%d" , a[i][j]);
}
}
}
I hope this code will be usefull.
Thank you.
I believe you're trying to be too smart with ternary operator, you can do it simpler way:
if (i < 3)
arraySum[i][j] = array2[i][j];
else
arraySum[i][j] = array1[i-3][j];
Listen to your compiler it would've told you what was wrong if you've compiled with -Wall -Wextra.
And if you insist on using ternary then this would probably be clearer:
arraySum[i][j] = (i < 3) ? array2[i][j] : array1[i-3][j];

Increasing number of rows in 2D c-array

Can't increase rows in 2d array, but columns is ok.
#include <stdio.h>
#include <stdlib.h>
it is working:
void increasecolumn(int ** mas, int* n, int m){
for (int i = 0; i < m; i++){
int* tmp = realloc(mas[i], sizeof (*mas[i]) * ((*n) + 1));
if (tmp){
mas[i] = tmp;
}
}
(*n) = (*n) + 1;
}
but increasing rows failed
void increaserow(int ** mas, int n, int* m){
int ** tmp = realloc(mas, sizeof(*mas) * ((*m) + 1));
if (tmp){
mas = tmp;
for (int i = 0; i < 1; i++){
mas[(*m) + i] = malloc(sizeof(*mas[(*m) + i]) * n);
}
}
(*m) = (*m) + 1;
}
int main(int argc, char * argv[]) {
int n = 3; // columns
int m = 2; // rows
int** mas = malloc(m*sizeof(*mas));
for(int i = 0; i < m; i++){
mas[i] = malloc(n*sizeof(*(mas[i])));
}
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
mas[i][j] = 0;
printf("%d ", mas[i][j]);
}
printf("\n");
}
printf("\n");
increasecolumn(mas, &n, m);
for (int i = 0; i < m; i++){
mas[i][n-1] = 1;
}
increaserow(mas, n, &m); // problem is here
for (int j = 0; j < n; j++){
mas[m-1][j] = 0;
}
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
printf("%d ", mas[i][j]);
}
printf("\n");
}
system("pause");
return 0;
}
I use this answer Resizing 2D Arrays in C like an example, something wrong.
The GNU Project Debugger on Windows:
warning: FTH: (9152): * Fault tolerant heap shim applied to current process. This is usually due to previous crashes. *
0 0 0
0 0 0
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401821 in main (argc=1, argv=0x7f1990) at D:\III Курс! II СЕМЕСТР\МатМодДослОп\stud\Untitled2.c:47
47: mas[m-1][j] = 0;

Segmentation fault in matrix multiplication using multiple threads

#include <stdio.h>
#include <pthread.h>
int arr[1000][1000];
int brr[1000][1000];
int h;
int f;
void *BMM(void *arg)
{
int* neo = (int*) arg;
int ne = *neo;
int sum = 0;
for(int i = 0; i < n; ++i)
{
sum += arr[x][i]*brr[x][f];
++f;
}
printf("%d\n", sum);
crr[x][h] = sum;
pthread_exit(NULL);
}
int main()
{
pthread_t* ar = malloc(3*sizeof(*ar));
printf("Enter the value of m and n\n");
scanf("%d %d",&m,&n);
for(int i = 0; i < m; ++i)
{
for(int j = 0; j < n; ++j)
{
scanf("%d",&arr[i][j]);
}
}
printf("Enter the value of p and q\n");
scanf("%d %d",&p,&q);
if(p != n)
{
printf("The matrix multiplication is not possible\n");
return 0;
}
int* id;
id = (int *)malloc(4*sizeof(int));
for(int i = 0; i < p; ++i)
{
for(int j = 0; j < q; ++j)
{
scanf("%d",&brr[i][j]);
}
}
for(x = 0; x < m; ++x)
{
for(z = 0; z < q; z+=4)
{
f = z;
h = z;
for(int k = 0; k < 3; ++k)
{
pthread_create(&ar[k],NULL,BMM,NULL);
}
for(int k = 0; k < 3; ++k)
{
pthread_join(ar[k],NULL);
}
}
}
for (int i = 0; i < m; ++i)
{
for(int j = 0; j < q; ++j)
{
printf("%d ",crr[i][j]);
}
printf("\n");
}
}
The above program is supposed to multiply two matrix by multiplying row one of matrix by all the columns of other matrix using 3 threads and then row two by all the other columns and so on and then store the respective values int another matrix but it is giving segmentation fault. Where am I going wrong?
I think your problem is here:
pthread_create(&ar[k],NULL,BMM,NULL);
^^^^
void *arg is NULL
and then:
void *BMM(void *arg)
{
int* neo = (int*) arg;
int ne = *neo; // Dereference NULL --> segmentation fault
Further this looks strange:
void *BMM(void *arg)
{
int* neo = (int*) arg;
int ne = *neo; // ne is never used !!
int sum = 0;
for(int i = 0; i < n; ++i) // Where does n come from ?
Perhaps it should be n instead of ne?
If n, x, f and h are global variables you are into trouble as all threads will work on the same variables. That would be real bad. Each thread needs it own variables.
BTW:
Always check the value returned by scanf - something like:
if (scanf("%d %d",&m,&n) != 2)
{
// Add error handling here
}
and
if (scanf("%d",&arr[i][j]) != 1)
{
// Add error handling here
}

C programming with functions

I have got some more problems with the code. This program ask the user to specify the nr of throws then it throws 3 dices and add these 3 dices to sum.
Then another function sorts the sum form the smallest to the largest with a bubble sorting algorithm.
the first two functions seems to work but the program does not print out the result of the 3rd sorting function.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 100
//This function ask the user for the amout of throws
int numberofthrows() {
int throws
printf("Type in the number of throws");
scanf("%d", &throws);
return throws;
}
//This function makes the random throws of 3 dices with regard to the number of throws
int filler(int thrownr, int dice1[MAX], int dice2[MAX], int dice3[MAX], int sum[MAX]) {
int i, nr;
srand(time(NULL));
for(i = 0; i <= thrownr; i++) {
nr = rand()%6;
dice1[i] = nr + 1;
nr = rand()%6;
dice2[i] = nr + 1;
nr = rand()%6;
dice3[i] = nr + 1;
sum[i] = dice1[i] + dice2[i] + dice3[i];
}
int j;
for(j = 0; j <= thrownr; j++) {
printf("%d ", dice1[j]);
printf("%d ", dice2[j]);
printf("%d ", dice3[j]);
printf("%d\n", sum[j]);
}
}
//This function sorts the result in form the sum array
int sorter(int thrownr, int sum[MAX], int sortsum[MAX]) {
int tmp, i, j, k, m;
for(i = 0; i <= thrownr; i++) {
sortsum[i] = sum[i];
}
for(m = 0; m <= 10; m++) {
for(j = 0; j <= thrownr; i++) {
if (sortsum[j] > sortsum[j+1]) {
tmp = sortsum[j];
sortsum[j] = sortsum[j+1];
sortsum[j+1] = tmp;
}
}
}
for(k = 0; k <= thrownr; k++) {
printf("%d\n", sortsum[k]);
printf("%d\n", sum[k]);
}
}
int main(void) {
srand(time(NULL));
int dice1[MAX];
int dice2[MAX];
int dice3[MAX];
int sum[MAX];
int sortsum[MAX];
int numberofthrows2;
numberofthrows2 = numberofthrows();
filler(numberofthrows2, dice1, dice2, dice3, sum);
sorter(numberofthrows2, sum, sortsum);
return 0;
}
The code for sorting is a bit wrong. Change
for(m = 0; m <= 10; m++)
To
for(m = 0; m <= thrownr-1; m++)
And
for(j = 0; j <= thrownr; i++)
To
for(j = 0; j < thrownr-m-1; i++)
To fix it. Also, call srand once at the start of main. Don't call it more than once in a program or you might get the same "random" numbers everytime you run your program.

I need to pass an array of structures to a function [large code]

I've been working on this for days but can't seem to make it work out.
Sorry in advance for the unholy length of this, so if anyone takes the time to go through it and try to understand this mess, I'd owe you.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct cart {
int id;
char *nume;
} cart;
typedef struct pach {
int id, idCartier, strada, numar, prioritate, codificare;
float greutate;
char* mesaj;
int adresa[18];
} pach;
typedef struct post {
int id, nrPachete;
int vector[50];
} post;
int citeste(int *nrP, cart *cartier, pach *pachet, int *nrC) {
printf("Punctul 1\n");
int i, j;
scanf("%d", nrC);
for (i = 0; i < *nrC; i++) {
cartier[i].id = i;
char aux[500];
scanf("%s", aux);
cartier[i].nume = malloc(strlen(aux) + 1);
cartier[i].nume = aux;
printf("%d %s\n", cartier[i].id, cartier[i].nume);
}
scanf("%d", nrP);
for (i = 0; i < *nrP; i++) {
pachet[i].id = i;
char aux[500];
for (j = 0; j < 18; j++)
scanf("%d", &pachet[i].adresa[j]);
scanf("%d %f", &pachet[i].prioritate, &pachet[i].greutate);
getchar();
fgets(aux, 256, stdin);
pachet[i].mesaj = malloc(strlen(aux) + 1);
pachet[i].mesaj = aux;
printf("%d\n", pachet[i].id);
for (j = 0; j < 18; j++)
printf("%d ", pachet[i].adresa[j]);
printf("\n%d %.6f ", pachet[i].prioritate, pachet[i].greutate);
printf("%s", pachet[i].mesaj);
}
return *nrP;
}
void extrage(int *nrP, pach *pachet) {
printf("\nPunctul 2\n");
int i, j;
for (i = 0; i < *nrP; i++) {
pachet[i].idCartier = 0;
pachet[i].strada = 0;
pachet[i].numar = 0;
for (j = 0; j < 5; j++)
pachet[i].idCartier += pachet[i].adresa[j] * pow(2, (4 - j));
for (j = 5; j < 10; j++)
pachet[i].strada += pachet[i].adresa[j] * pow(2, (9 - j));
for (j = 10; j < 18; j++)
pachet[i].numar += pachet[i].adresa[j] * pow(2, (17 - j));
printf("%d %d ", pachet[i].id, pachet[i].idCartier);
printf("%d %d\n", pachet[i].strada, pachet[i].numar);
}
}
void distribuie(int *nrP, pach *pachet, post *postas, int *nrC, cart *cartier) {
printf("Punctul 3\n");
int i, j;
for (i = 0; i < *nrC; i++) { // FOR-1A
postas[i].nrPachete = 0;
postas[i].id = i;
for (j = 0; j < 50; j++)
postas[i].vector[j] = 0;
}
for (i = 0; i < *nrC; i++) { // FOR-1B
for (j = 0; j < *nrP; j++) {
if (cartier[i].id == pachet[j].idCartier) {
postas[i].vector[postas[i].nrPachete] = pachet[j].id;
postas[i].nrPachete++;
}
}
printf("%d %d ", postas[i].id, postas[i].nrPachete);
for (j = 0; j < postas[i].nrPachete; j++)
printf("%d ", postas[i].vector[j]);
printf("\n");
}
}
void ordoneaza(pach *pachet, int *nrC, post *postas) {
printf("Punctul 4\n");
pach aux;
int i, j, k = 0, schimbat = 1;
for (i = 0; i < *nrC; i++) {
while (schimbat) {
schimbat = 0;
for (j = 0; j < postas[i].nrPachete - k; j++)
if (pachet[postas[i].vector[j]].prioritate < pachet[postas[i].vector[j+1]].prioritate) {
aux = pachet[postas[i].vector[j]];
pachet[postas[i].vector[j]] = pachet[postas[i].vector[j+1]];
pachet[postas[i].vector[j+1]] = aux;
schimbat = 1;
}
k++;
}
k = 0;
schimbat = 1;
for (j = 0; j < postas[i].nrPachete; j++) {
for (k = j; k < postas[i].nrPachete; k++) {
if (pachet[postas[i].vector[j]].prioritate == pachet[postas[i].vector[k]].prioritate)
if (pachet[postas[i].vector[j]].greutate < pachet[postas[i].vector[k]].greutate) {
aux = pachet[postas[i].vector[j]];
pachet[postas[i].vector[j]] = pachet[postas[i].vector[k]];
pachet[postas[i].vector[k]] = aux;
}
}
}
}
for (i = 0; i < *nrC; i++)
for (j = 0; j < postas[i].nrPachete; j++) {
postas[i].vector[j] = pachet[postas[i].vector[j]].id;
}
for (i = 0; i < *nrC; i++) {
printf("%d %d ", postas[i].id, postas[i].nrPachete);
for (j = 0; j < postas[i].nrPachete; j++)
printf("%d ", postas[i].vector[j]);
printf("\n");
}
}
int main() {
int nrP, nrC;
pach pachet[1600];
post postas[32];
cart cartier[32];
citeste(&nrP, &cartier[32], &pachet[1600], &nrC);
extrage(&nrP, &pachet[1600]);
distribuie(&nrP, &pachet[1600], &postas[32], &nrC, &cartier[32]);
ordoneaza(&pachet[1600], &nrC, &postas[32]);
return (0);
}
Short info on what the program does:
The citeste function should read the cartier and pachet structures. All of them. And then print those in a bit different format.
The extrage function should take every pachet, and use the adresa (written in BINARY) to convert its 3 parts and obtain the strada, numar and idCartier. Then also print those.
Distribuie checks if the pachet is distributed to a postas (distributed means pachet.idCartier == postas.id), if not it distributes it.
Ordoneaza takes every postas's vector and sorts it after the prioritate (or greutate if the prioritate-s are equal).
But it doesn't work as intended and also gives weird Segmentation Faults.
For example if I comment out the distribuie function, it gives me segfault right after extrage. If I put it back, it gives segfault right after doing it. And if I uncomment everything, it gives segfault at the end again.
If anyone actually read all of this and would be willing to reply, I'd highly appreciate it. Any bit of advice helps!
I did not read your code, but your title said you had trouble passing array of structures. I am attaching a working snippet hope it will help you get around your problem.
#include<stdio.h>
typedef struct employee{
int empId;
char name[10];
}EMP;
void arrayOfStruct(EMP *a, int size)
{
printf("%d\t%d",a[0].empId,a[3].empId);
}
int main()
{
EMP NC[4];
NC[0].empId = 9;
NC[3].empId = 2;
arrayOfStruct(&NC[0],sizeof(NC)/sizeof(NC[0]));
}
with the help of size you can never go beyond the memory allocated for structures.
In case you, want to pass higher dimensional arrays, you have to hard code all the size of arrays except the outer most.
void arrayOfStruct(EMP a[][4], int size)
{
// to do
}
int main()
{
EMP NC[2][4];
...
arrayOfStruct(NC,sizeof(NC)/sizeof(NC[0]));
}
as you see, I did not specify the higher most size of array, which I am passing via other arguement.
Why do I need to specify size of inner dimensions ?
Lets take an example, for suppose you have int[4][4], and you are trying to pass array to a function via int[3][], how does a compiler know how many inner blocks to create, in other case via int[][3], the compiler can easily understand that it has to make inner block of size 3 for each outer array.

Resources