I am trying to make multithread array sorting program in c. But when I run the program, I get an "segmentation fault" error.
Can someone help?
What should I change? First array should be 300 the other should be 500. We sort sequences separately first. After that merge 2 sorted sequences. I use "gcc -pthreads -0 soru1 soru1.c" and "./soru1" commands.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#define size 800
int orginal_dizi[size], dizi1[300], dizi2[500], dizi3[size];
int sayi,a=1;
int boyutbul(int *the)
{
int number=-1;
while(the[++number]!='\0'){}
return number;
}
void*runner(void *param)
{
int temp,i,k;
int *bolum = param;
sayi = boyutbul(bolum);
printf("\n----------unsorted %d. array-----------\n\n",a);
for(i=0; i<sayi;i++)
printf("%d\n", bolum[i]);
for(i=0; i<sayi;i++)
{
for(k=0; k<(sayi-i-1);k++)
{
if(bolum[k]>bolum[k+1])
{
temp=bolum[k];
bolum[k]=bolum[k+1];
bolum[k+1]=temp;
}
}
}
printf("\n----------sorted %d. array-----------\n\n",a);
for(i=0; i<sayi;i++)
printf("%d\n", bolum[i]);
a++;
pthread_exit(0);
}
int main()
{
pthread_t tid1,tid2, tid3;
int i=0;
while(i<size)
{
int yenisayi=1+rand()%1500;
int aynimi=0, j=0;
while(j<i)
{
if(orginal_dizi[j]==yenisayi)
{
aynimi=1;
break;
}
j++;
}
if(aynimi)
continue;
orginal_dizi[i]=yenisayi;
i++;
}
for(i=0;i<size;i++)
{
if(i<(300))
{
dizi1[i]=orginal_dizi[i];
}
else
{
dizi2[i-(500)-1]= orginal_dizi[i];
}
}
pthread_create(&tid1,NULL,runner,(void *)dizi1);
pthread_join(tid1,NULL);
pthread_create(&tid2,NULL,runner,(void *)dizi2);
pthread_join(tid2,NULL);
for(i=0; i<size;i++)
{
if(i<300)
{
dizi3[i]=dizi1[i];
}
else
{
dizi3[i]=dizi2[i-500];
}
}
pthread_create(&tid3,NULL,runner,(void *)dizi3);
pthread_join(tid3,NULL);
FILE *fp;
if((fp=fopen("son.txt","w"))== NULL)
printf("Dosya acilamadi.");
for(i=0;i<size;i++)
{
fprintf(fp, "%d\n", dizi3[i]);
}
fclose(fp);
return 0;
}
There is no multithreading in this program: every thread is immediately joined; noting runs in parallel.
The real problem is in boyutbul, which tries to figure out the length of the array by looking for '\0'. The way you initialize the arrays, there is no guarantee that they would have the terminating 0 (in fact, they wouldn't have any zeroes), so the program is doomed to access them beyond the bounds. This is UB.
Related
I am having some trouble understanding this code since I am new to pthread programming. From what I understand, we create N threads and execute the run function on them, which only prints the thread number. Am I missing something?
Is there any advantage of using snprintf (with buffers) over printf in this particular case? Could this program be improved any further?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
static int N = 5;
static void* run(void *arg)
{
int *i = (int *) arg;
char buf[123];
snprintf(buf, sizeof(buf), "thread %d", *i);
return buf;
}
int main(int argc, char *argv[])
{
int i;
pthread_t *pt = NULL;
for (i = 0; i < N; i++) {
pthread_create(pt, NULL, run, &i);
}
return EXIT_SUCCESS;
}
First of all, your threads return garbage. Deferencing the pointer returned would be Undefined Behaviour because it points to storage that no longer exists after the function returns. Good thing nothing used the pointer.
Next, the threads don't print anything because snprintf outputs to an array, not stdout.
Furthermore, the threads would print garbage if you switched to printf because the same pointer is passed to to all threads.
And that's assuming the threads have a chance to run since main doesn't wait for the threads to finish. You gotta join them.
Fixed:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define N 5
static void *run(void *arg) {
size_t job = *(size_t*)arg;
printf("Job %zu\n", job);
return NULL;
}
int main(int argc, char *argv[]) {
size_t jobs[N];
pthread_t threads[N];
for (size_t i=0; i<N; ++i) {
jobs[i] = i;
pthread_create(threads+i, NULL, run, jobs+i);
}
for (size_t i=0; i<N; ++i) {
pthread_join(threads[i]);
}
return EXIT_SUCCESS;
}
It's also common to pass an integer cast to a pointer.
#include <inttypes.h>
#include <pthread.h>
#include <stdio.h>
#include <stdint.h>
static void *run(void *arg) {
size_t job = *(uintptr_t*)arg;
printf("Job %" PRIuPTR "\n", job);
return NULL;
}
int main(int argc, char *argv[]) {
pthread_t threads[N];
for (uintptr_t i=0; i<N; ++i) {
pthread_create(threads+i, NULL, run, (void*)i);
}
for (uintptr_t i=0; i<N; ++i) {
pthread_join(threads[i]);
}
return EXIT_SUCCESS;
}
I am trying to create a structure inside a function and i am trying to use it. But when I am comparing two values from structure I am getting this message :
"C:\Users\hp\Desktop\prgm\cap.c||In function 'fnumber':|
C:\Users\hp\Desktop\prgm\cap.c|
72|error: request for member 'f_value' in something not a structure or union|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
this is my code:-
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
/*
* Complete the function below.
*/
int fnumber(long input1,int input2_size, int* input2)
{
int i, j, k, count[input2_size],temp=0;
int arr_temp[input2_size];
struct smaller{
int position;
int f_value;};
struct smaller list[input2_size];
struct smaller temp1;
memccpy(arr_temp, input2, input2_size,sizeof(int));
for(i=0; i<input2_size;i++)
{
for(j=i+1; j<=input2_size;i++)
{
if(arr_temp[i]>arr_temp[j])
{
temp=arr_temp[i];
arr_temp[i]=arr_temp[j];
arr_temp[j]=temp;
}
}
}
for(i=0; i<input2_size;i++)
{
if(i>1)
count[i]=input2[i];
for(j=0;j<input2[i-1];j++)
{
count[i]+=arr_temp[j];
}
}
/* for(i=0;i<input2_size-1;i++)
{
for(j=i+1;j<input2_size;j++)
{
if(count[i]>count[j])
{
temp=count[i];
count[i]=count[j];
count[j] = temp;
}
}
}*/
for(i=0,j=0;i<input2_size;i++)
{
if(count[i]<=input1)
continue;
else
{
list[j].position=i;
list[j].f_value=count[i];
j++;
}
}
for(i=0;i<input2_size-1;i++)
{
for(j=i+1;j<input2_size;j++)
{
if(list[i].f_value>list[j.f_value])
{
temp1=list[i];
list[i]=list[j];
list[j]=temp1;
}
}
}
return list[0].position;
}
int main() {
int output = 0;
long ip1;
scanf("%ld", &ip1);
int ip2_size = 0;
int ip2_i;
scanf("%d\n", &ip2_size);
int ip2[ip2_size];
for(ip2_i = 0; ip2_i < ip2_size; ip2_i++) {
int ip2_item;
scanf("%d", &ip2_item);
ip2[ip2_i] = ip2_item;
}
output = fnumber(ip1,ip2_size,ip2);
printf("%d\n", output);
return 0;
}
if(list[i].f_value>list[j.f_value])
You misspelled list[j].f_value as list[j.f_value].
Also, memccpy should be memcpy.
I want to multiply 2 2D arrays (C[i][j]=A[i][j]*B[i][j] ) in C using shared memory . I have to calculate each multiplication separate calling compute in child process .
A=lm matrix and B=uv matrix , so i have to make l*v child processes where i call compute with execv/execl . I get an segmentation fault (core dumped)
main :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/stat.h>
int main(int argc,char *argv[])
{
FILE *fp;
int **A;
int **B;
int **C;
int l,m,u,v,size;
int pid;
int segment_id;
int *shared_memory;
int i,j,tmp;
//---------------------------------------------
//Reading arrays
fp=fopen("/home/ubuntu-gnome/Desktop/arrays.txt","r");
fscanf(fp,"%d %d",&l,&m);
*A=(int *)malloc(l*sizeof(int));
for(i=1;i<=l;i++){
A[i]=(int *)malloc(m*sizeof(int));
}
for(i=1;i<=l;i++){
for(j=1;j<=m;j++){
fscanf(fp,"%d ",&tmp);
A[i][j]=tmp;
}
}
fscanf(fp,"%d %d",&u,&v);
*B=(int *)malloc(u*sizeof(int));
for(i=1;i<=u;i++){
B[i]=(int *)malloc(v*sizeof(int));
}
for(i=1;i<=u;i++){
for(j=1;j<=v;j++){
fscanf(fp,"%d",&tmp);
B[i][j]=tmp;
}
}
fclose(fp);
//------------------------------------------------------------------
//printing arrays
for(i=1;i<=l;i++){
for(j=1;j<=m;j++){
printf("%d ",A[i][j]);
}
printf("\n");
}
printf("\n*3");
for(i=1;i<=u;i++){
for(j=1;j<=v;j++){
printf("%d" ,B[i][j]);
}
printf("\n");
}
//---------------------------------------------------------------
//Shared Memory
size=sizeof(int)*l*m*u*v*l*v;
segment_id = shmget(IPC_PRIVATE,size,S_IRUSR|S_IWUSR);
shared_memory=(int *)shmat(segment_id,NULL,0);
for(i=1;i<=l;i++)
for(j=1;j<=m;j++)
shared_memory[i*j+j]=A[i][j];
for(i=(l+1);i<=(u+l);i++)
for(j=(1+m);j<=(v+m);j++)
shared_memory[i*j+j]=B[i][j];
//-------------------------------------------------------------------
// Multiplication error beacuse column of A!= row of B
if (u!=m){
printf("\nMultiplication error !\n");
exit(1);
}
//------------------------------------------------------------------
for (i=1;i<=l;i++){
for (j=1;j<=v;j++){
pid=fork();
if(pid>=0){//fork was successful
if (pid==0){//child proccess
execl("/home/ubuntu-gnome/Desktop/compute","compute", (char)segment_id,(char)size,(char)i,(char)j,(char)m,(char)l,(char)v,NULL);
}
else //parent proccess
wait(0);
}
else // fork failed
{
printf("\n Fork failed, quitting!!!!!!\n");
return 1;
}
}
}
//-------------------------------------------------
//filing C
*C=(int *)malloc(l*sizeof(int));
for(i=1;i<=l;i++){
C[i]=(int *)malloc(v*sizeof(int));
}
for(i=1;i<=l;i++){
for(j=1;j<=v;j++){
B[i][j]=shared_memory[m*(l*v)+i];
}
}
//-------------------------------------------------
//printing C=A*B
for(i=1;i<=l;i++){
for(j=1;j<=v;j++){
printf("%d ",C[i][j]);
}
printf("\n");
}
/* now detach the shared memory segment */
shmdt(shared_memory);
/* now remove the shared memory segment */
shmctl(segment_id, IPC_RMID, NULL);
return 0;
}
compute:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/stat.h>
int main(int argc,char *argv[])
{
int segment_id;
int *shared_memory;
int key =atoi(argv[0]);
int size =atoi(argv[1]);
int row=atoi(argv[2]);
int col=atoi(argv[3]);
int m=atoi(argv[4]);
int l=atoi(argv[5]);
int v=atoi(argv[6]);
int i,j,Mul;
shared_memory=(int *)shmat(segment_id,NULL,0);
for (i=row;i<=m;i++){
for (j=col;j<=m;j++){
Mul=Mul+shared_memory[i]*shared_memory[l*m+j];
}
shared_memory[m*(l*v)+i]=Mul;
Mul=0;
}
return 0;
}
arrays.txt :
6 2
2 4
4 8
1 0
3 12
7 2
8 9
2 4
2 4 3 12
6 7 8 5
AFAIK, It should be like that,
int **A = (int **)malloc(l * sizeof(int *));
for (i=0; i<l; i++)
A[i] = (int *)malloc(m * sizeof(int));
Also, you should start arrays from 0. (Why?)
for(i=0;i<l;i++){
for(j=0;j<m;j++){
fscanf(fp,"%d ",&tmp);
A[i][j]=tmp;
}
}
This is a Matrix multiplication code. It creates a thread to multiply each row of the first matrix to the second matrix and saves the result in matrix C.
It gives an error in the pthread_create line expected primary-expression before 'void'.
I run this code on ubunto 13.10 virtual machine.
Thanks in advance.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
struct matrices
{
int matrixA[10][10];
int matrixB[10][10];
int matricC[10][10];
int r1,r2,c1,c2;
}*ptr;
int p;
void *matrixMul(void *);
int main()
{
int i=0,j=0;
pthread_t threads[10];
ptr=(struct matrices*)malloc(sizeof(struct matrices));
printf("Enter size of first matrix(Rows then Columns)");
scanf("%d",&(ptr->r1));
scanf("%d",&(ptr->c1));
printf("Enter elements of first array : ");
for(i=0; i<ptr->r1; i++)
{
for(j=0; j<ptr->c1; j++)
{
scanf("%d",&ptr->matrixA[i][j]);
}
}
printf("Enter size of second matrix(Rows then Columns)");
scanf("%d",&(ptr->r2));
scanf("%d",&(ptr->c2));
if(ptr->c1!=ptr->r2)
{
printf("Dimensions ERRORR! ");
}
else
{
printf("Enter elements of second array : ");
for(i=0; i<ptr->r2; i++)
{
for(j=0; j<ptr->c2; j++)
{
scanf("%d",&ptr->matrixB[i][j]);
}
}
for(i=0;i<ptr->r1;i++)
{
for(j=0;j<ptr->c2;j++)
{
ptr->matricC[i][j]=0;
}
}
for (p=0;p<ptr->r1;p++)
{
**********pthread_create(&threads[p],NULL, *matrixMul,void &p);**********
}
for(i=0;i<ptr->r1;i++)
{
pthread_join(threads[i],NULL);
}
for(i=0;i<ptr->r1;i++)
{
for(j=0;j<ptr->c2;j++)
{
printf("%d",ptr->matricC[i][j]);
}
}
}
return 0;
}
void *matrixMul(void *rownum)
{
int *i;
int n=0,m=0;
i=(int*)rownum;
for(n=0;n<ptr->c2;n++)
{
for(m=0;m<ptr->c1;m++)
{
ptr->matricC[*i][n]+=(ptr->matrixA[*i][m])*(ptr->matrixB[m][n]);
}
}
return NULL;
}
Your code contains minor error, but the logic is correct, don't worry.
I downloaded the code and tested it on my machine, so please note the following:
This line should be written this way...
pthread_create(&threads[i],NULL, matrixMul, &i);
Because according to the specs of pthread library that pthread_create should take void pointer to the runner function and void pointer to the parameter. You don't need to add (void *) because you already declared your runner function matrixMul as void *.
Your primary error here was (void) &i and it should be &i only as you already delcaired this parameter as void * in the runner function's prototype. You shall too pass the runner function like this &matrixMul.
Some other notes: "Code Review"
You shouldn't put your logic in the else statement, you can simply after printf("Dimensions ERRORR! "); write exit(-1); because this is basically what you do if the dimensions error.
Check for the return value (status) of pthread_create and pthread_join
The code below is supposed to work as a shell. It has the previous and next option, a history like feature, the exit and the execute command.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BUFFER_SIZE 256
#define HISTORY_LENGTH 128
int executeCommand(char*cmd)
{
return(!strcmp(cmd,"e\n"));
}
int exitCommand(char*cmd)
{
return (!strcmp(cmd,"exit\n"));
}
int previousCommand(char*cmd)
{
return (!strcmp(cmd,"p\n"));
}
int nextCommand(char*cmd)
{
return (!strcmp(cmd,"n\n"));
}
void execute(char *line)
{
line[strlen(line)-1]='\0';
char **arguments;
char* temp;
int i=0;
arguments=(char**)malloc(sizeof(char)*10);
temp=strtok(line," ");
arguments[i]=malloc(strlen(temp)*sizeof(char));
if(arguments[i]!=NULL)
{
strcpy(arguments[i],temp);
i++;
}
else
{
printf("Out of memory");
}
while(temp!=NULL)
{
temp=strtok(NULL," ");
if(temp==NULL){
arguments[i]=NULL;
}
else{
arguments[i]=malloc(strlen(temp)*sizeof(char));
if(arguments[i]!=NULL)
{
strcpy(arguments[i],temp);
i++;
}
}
}
printf("%s ",arguments[0]);
printf("%s ",arguments[1]);
printf("%s ",arguments[2]);
execvp(arguments[0],arguments);
}
int main(int argc, char*argV[]) {
int i;
char *cmd=(char*)malloc(sizeof(char)*BUFFER_SIZE);
char **history=NULL;
int historylength=0;
int currentCommand=0;
history=(char**)malloc(sizeof(char)*BUFFER_SIZE);
do{
fgets(cmd,BUFFER_SIZE-1,stdin);
if(exitCommand(cmd))
break;
else
if(previousCommand(cmd))
{
if(currentCommand>0)
printf("%s",history[--currentCommand]);
else if(currentCommand==0)
{
currentCommand=historylength;
printf("%s",history[--currentCommand]);
}
}
else
if(nextCommand(cmd))
{
if(currentCommand<historylength)
printf("%s",history[currentCommand++]);
}
else
if(executeCommand(cmd))
{
execute(history[--currentCommand]);
}
else
{
history[historylength]=malloc(strlen(cmd)*sizeof(char));
if(history[historylength]!=NULL)
{
strcpy(history[historylength],cmd);
currentCommand=++historylength;
}
else
{
printf("Out of memory");
break;
}
}
} while(1);
free(cmd);
for(i=0;i<historylength;i++)
free(history[i]);
free(history);
return 0;
}
I want to make this work for the function cat. I type in the e cat main.c and I expect it to execute the cat command but it's not doing anything, what am I doing wrong here? I'm not a pro at this so I appreciate all the help.
This is incorrect:
arguments=(char**)malloc(sizeof(char)*10);
as arguments is a char**, so the code needs to allocate sizeof(char*). Change to:
arguments = malloc(10 * sizeof(*arguments));
Same mistake for history also. Additionally, see Do I cast the result of malloc?
There is one char less than required being allocated for the char* as strcpy() writes a terminating null character. Change:
arguments[i]=malloc(strlen(temp)*sizeof(char));
to:
arguments[i] = malloc(strlen(temp) + 1);
sizeof(char) is guaranteed to be 1 and can be omitted from the size calculation.
Prevent i from exceeding the bounds of the memory allocated for arguments. As the code currently stands there is no protection to prevent i from exceeding 9 (0 to 9 are the valid values for i as arguments was allocated 10 elements).