0

I am trying to do an assignment in which I am to use multiple threads to sort input from a file, but when I try to use the array of structs to store the information I need to recover after the threads, I get a segmentation fault. I am not sure why it is causing the fault, as according to the sources I have.

This is the main file, Threads.c The seg fault is in the for loop, and the causing line is desginated by a comment. Sort Method is another function I did not in

#include "threads.h"
Threads* threadArray[4];
int linesPerThread;
int extraLines;

main(int argc, char *argv[]){
 int n;

 if( argc != 4){
  printf("Wrong Number of Arguements!\n");
  return;
}
  n = atoi(argv[1]);
 char *inName = argv[2];



*threadArray = (Threads*) (*threadArray, n*sizeof(Threads));  




FILE* file = fopen(inName, "r");
 if(!file){
printf("invalid file Name \n");
return;}

int lines = 0;
char xyz[5000]; //makes fgets happy
while(fgets(xyz, 5000, file) != NULL){
  lines = lines+1;
}
fclose(file);
linesPerThread = lines / n;


 extraLines = lines - linesPerThread;

 int i =0;
 int methodCounter =1;


 printf("Right before Loop \n \n");

 for(i; i < n; i++){

   printf("first part of loop \n");
 \\The ling below here Seg Faults.
   (*threadArray + i)->id = i;

   printf("right after first ThreadArray access \n");
   if(methodCounter < 3){
 printf("method counter 1\n");
(*threadArray+i)->methodID = methodCounter;
 methodCounter++;
   }else{
 printf("method counter condition 2 \n");
(*threadArray + i)->methodID = 3;
   methodCounter = 1;}
   if(extraLines > 0){
 printf("extra Lines condition 1 \n");
(*threadArray+i)->lines = linesPerThread +1;
 extraLines= extraLines -1;
   }else{
 printf("extraLines condition 2 \n");
 (*threadArray+i)->lines = linesPerThread;
   }
   printf("Right before Thread Creation \n \n");
   pthread_t tID;
   pthread_create(&tID, NULL, sortMethod, (void*) &((*threadArray+i)->id));
   (*threadArray+i)->threadID = tID;
   printf("right after thread creation \n \n");
 }
 printf("right after loop \n \n");
 int c=0;

 printf("before thread joining \n");
 for(c; c< n; c++){
   pthread_join( (*threadArray+ c)->threadID, NULL);
 }


 }

And this is the header file, Threads.h

#include <sys/time.h>
#include <stdio.h> 
#include <pthread.h>
#include <stdlib.h>
#include <string.h>

typedef struct{
  int id;
  int lines;
  pthread_t threadID;
  int methodID;
}Threads;

void* sortMethod(void*ptr);
int main(int argc, char *argv[]);

Any help you can offer would be greatly appreciated.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • If your array could be accessed by more than one thread you should protect it with mutex (or semaphore): Please take a look at the solution proposed in this post : http://stackoverflow.com/questions/3144349/boost-threads-mutex-array – Mehdi Karamosly Jan 02 '13 at 23:55

1 Answers1

0

In the line

*threadArray = (Threads*) (*threadArray, n*sizeof(Threads));  

you are setting threadArray[0] to (Threads*)(n*sizeof(Threads). You probably want a realloc or a calloc in that line.

As it stands,

(*threadArray, n*sizeof(Threads))

is a comma-expression, and the value of that comma-expression is cast to Threads*.

Since you never allocated memory to any of the elements of threadArray,

(*threadArray + i)->id = i;

dereferences invalid pointers. Since the array is static, the pointers are originally initialised to null pointers, you only set threadArray[0] to a different value (but that doesn't point to valid memory either, in all probability).

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • D'oh! I forgot to call realloc. I feel very silly. Thank you so much, I would never have spotted it. – Nicholas Klein Jan 02 '13 at 23:50
  • Now that you got that all figured out, [do not cast `malloc`](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – Joe Jan 03 '13 at 00:05