0

This is a program made in C that compiles fine using gcc filename.c -o file -pthread. However when I go to run the program is tells me there is a segmentation fault and I am not sure how to fix it. This program is meant to make random integers in an array then compare how long it takes to find the 10 largest and 10 lowest numbers using a different amount of threads for reach iteration of the program.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>

#define arraySize 10000
#define lval 0 
#define hval 50000
#define maxthread 100

int num[arraySize];
int maxs[maxthread];
int mins[maxthread];
int threadsize;
int threadnum = 0;

void fill(){
    int i;
    int tmp[hval];
    for(i = lval;i < hval;i++)tmp[i] = i;
    for(i = 0;i < arraySize;i++){
        int t= i + rand()%(hval - 1);
        int temp = tmp[i];
        tmp[i] = tmp[t];
        tmp[t] = temp;
        num[i] = tmp[i];
    }
}

void print(){
    int i;
    printf("First 10 Numbers are: \n");
    for(i = 0;i < 10;i++)printf("\t%d\n",num[i]);
    printf("\n\nLast 10 Numbers: \n");
    for(i = (arraySize - 10);i < arraySize;i++)printf("\t%d\n",num[i]);
}

void *getminmax(void *arg){
    int i,n = threadnum++;
    int max = lval,min = hval;
    for(i = n*(arraySize / threadsize);i < (n + 1)*(arraySize / threadsize);i++){
        if (num[i] > max)max = num[i];
        if (num[i] < min)min = num[i];
    }
    maxs[n] = max;
    mins[n] = min;
    printf("Threads:%d Min: %d Max%d Thread Num: %d\n",threadsize,min,max,n);
}

void search(){
    int max = lval, min = hval;
    int i;
    int start = clock();
    pthread_t threads[threadsize];
    for(i = 0;i < threadsize;i++)
        pthread_create(&threads[i],NULL,getminmax,(void*)NULL);
    for(i = 0;i < threadsize;i++)
        pthread_join(threads[i],NULL);
    for(i = 0;i < threadsize;i++){
        if(maxs[i] > max)max = maxs[i];
        if(mins[i] < min)min = mins[i];
    }
    int end = clock();
    int d = end - start;
    printf("Threads %d Min: %d Time Taken: %d \n\n",threadsize,min,max,d);
}

int main(){
    fill();
    print();
    threadsize = 2;
    threadnum = 0;
    search();
    threadsize = 10;
    threadnum = 0;
    search();
    threadsize = 100;
    threadnum = 0;
    search();
    return 0;
}
yano
  • 4,827
  • 2
  • 23
  • 35
amon
  • 1
  • "*I am not sure how to fix it*". Good time to learn to debug. Run you program in a debugger. At a minimum it will immediately give you the exact line of code that triggers the seg fault. Can also use it to trace the program as it runs. – kaylum Dec 04 '21 at 21:37
  • 1
    `int t= i + rand()%(hval - 1);` Worst case scenario, `i==9999`, `rand()%(hval - 1)==49999` (although depends on `RAND_MAX` defined in stdlib.h, so maybe less than 49999), but seems plausible those added together can be > 49999, so `tmp[t]` will be out of bounds, invoking UB. You can put a conditional breakpoint on `t` to see if that is ever true, or try to figure out the max value that `rand()` can return. You also need to [seed `rand()`](https://stackoverflow.com/questions/822323/how-to-generate-a-random-int-in-c) – yano Dec 04 '21 at 21:47

1 Answers1

0

There are few obvious bugs in your program.

  1. As yano pointed out, t = i + rand()%(hval - 1); will produce a t in the range between 0 and arraySize + hval - 2. That later value is well outside the valid range for accessing tmp[t] and is likely the cause of the segmentation fault.

    You probably meant this instead: t = (i + rand()) % (hval - 1);

  2. The construct below is a data race. You are not at all guaranteeing distinct ns for different threads.

  int n = threadnum++;

The usual fix for problem 2 is to pass the thread number as the arg (which you didn't use).

Employed Russian
  • 199,314
  • 34
  • 295
  • 362