We help IT Professionals succeed at work.

fgets or pthread causing a segmentation fault

1,780 Views
Last Modified: 2013-12-26
I get a segmentation fault when I run this program. "Producer created" appears on the screen. After I type in a character a  "Segmentation fault occurs. If I don't enter data the "Consumer created" appears and I still get a segmentation fault. I'm just trying to get thread one to read  the stdin data and thread 2 to write the data to stdout. I'm not that familiar with pthread_create, how it shares data, or all these pointers. I know something is overflowing in memory but I don't know how to fix the problem.
It may be that fgets and fputs that are causing problems too. Can someone please help me with this program? Thanks

#include <pthread.h>
#include <stdio.h>
void *Producer(void *data);
void *Consumer(void *data);

int main()
 {
  pthread_t t1, t2;
 
  printf("main started\n");
  pthread_create(&t1, NULL, Producer, NULL);
  sleep(3);
  pthread_create(&t2, NULL, Consumer, NULL);
  pthread_join(t1, NULL);
  pthread_join(t2, NULL);
  printf("main done \n");
}
                                                                       
void *Producer(void *data)
{   int i=0;
   
      printf("Producer created\n");
      for(i;i=1;i++)
           {
                  sleep(3);
            fgets(data,27,stdin);
                  printf("data read \n");
                  sleep(3);
           }    
}

void *Consumer(void *data)
 {
  int i=0;
  printf("Consumer created\n");
  for (i ; i= 1; i++)      
  fputs(data,stdout);
 
}
Comment
Watch Question

Commented:
> for(i;i=1;i++)

for(i; i == 1; i++)

Author

Commented:
Thanks for your quick response...it's always those little things that cause problems. Still, after that fix, I don't think I'm passing anything from stdin to data. The Producer function doesn't printf("data read \n"). Consumer created is printed but no input goes to stdout. If I change the for loop in Producer to while(1) the segmentation fault returns.
Is fgets the problem?

Commented:
To be honest I don't know much about threads :)
But when I corrected both the for loops for the error then the program seems to work fine. I am wondering where "data" is getting stored?
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
You are passing NULL as data and then use

            fgets(data,27,stdin);

That for sure will cause a segfault, since it is equivalent to

            fgets(NULL,27,stdin);

Try passing a valid buffer, i.e.

int main()
 {
  pthread_t t1, t2;
  char in[28];
  char out[28];
 
  printf("main started\n");
  pthread_create(&t1, NULL, Producer, (void*) out);
  sleep(3);
  pthread_create(&t2, NULL, Consumer, (void*) in);
  pthread_join(t1, NULL);
  pthread_join(t2, NULL);
  printf("main done \n");
}

Author

Commented:
That helped, but stdin and stdout are not getting my input. When I run this code:

#include <pthread.h>
#include <stdio.h>
void *Producer(void *data);
void *Consumer(void *data);

int main()
 {
  pthread_t t1, t2;
  char in[28];
  char out[28];
  printf("main started\n");
  pthread_create(&t1, NULL, Producer,(void*) in);
  sleep(3);
  pthread_create(&t2, NULL, Consumer, (void*)out);
  pthread_join(t1, NULL);
  pthread_join(t2, NULL);
  printf("main done \n");
}
                                                                           
void *Producer(void *data)
{   int i=0;
   
      printf("Producer created\n");
      for(i;i==1;i++)
           {
                  sleep(3);
            fgets(data,27,stdin);
                  printf("data read \n");
                  sleep(3);
           }    
}

void *Consumer(void *data)
 {
  int i=0;
  printf("Consumer created\n");
  for (i;i==1;i++)      
  {
        fputs(data,stdout);
        printf("data out \n");
  }  
  return NULL;
}

The results are:

main started
Producer created
abc
Consumer created
main done
[dwiseman@06 ~/project]$ abc
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
The loop conditions are bogus. I is assigned a 0 the loop executed only when 'i==1' - IOW never. Make that

      for(i = 0;i<1;i++)
           {
                  sleep(3);
            fgets(data,27,stdin);
                  printf("data read \n");
                  sleep(3);
           }    

Commented:
Just a suggestion, shouldn't you use a single data pointer instead of "in" and "out"
....
  char *data;

  printf("main started\n");
  pthread_create(&t1, NULL, Producer,(void*) data);
  sleep(3);
  pthread_create(&t2, NULL, Consumer,(void*) data);
.....
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
I'd take that as a next step when the whole thing works ;o)

Commented:
I removed the loop as suggested by JKR and the program now works fine.

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *Producer(void *data);
void *Consumer(void *data);

int main()
 {
  pthread_t t1, t2;
  char *data;

  printf("main started\n");
  pthread_create(&t1, NULL, Producer, data);
  sleep(3);
  pthread_create(&t2, NULL, Consumer, data);
  pthread_join(t1, NULL);
  pthread_join(t2, NULL);
  printf("main done \n");
}

void *Producer(void *data)
{
      printf("Producer created\n");
      fgets(data,27,stdin);
      printf("data read \n");
}

void *Consumer(void *data)
{
        printf("Consumer created\n");
        fputs(data,stdout);
}

Author

Commented:
I fixed the for loops...the program flows like it should. Still, I got no stdin or stdout. So, I changed the function arguments from in/out to data....back to a Segmentation fault problem.

#include <pthread.h>
#include <stdio.h>
int main()
 {
  pthread_t t1, t2;
  void *Producer(void *data);
  void *Consumer(void *data);
  char in[28];
  char out[28];
  char *data;
  printf("main started\n");
  pthread_create(&t1, NULL, Producer,(void*)data);
  sleep(3);
  pthread_create(&t2, NULL, Consumer, (void*)data);
  pthread_join(t1, NULL);
  pthread_join(t2, NULL);
  printf("main done \n");
}
                                                                             
void *Producer(void *data)
{   int i;
    printf("Producer created\n");
      for(i=0;i<1;i++)
           {
                  sleep(3);
            fgets(data,27,stdin);
                  printf("data read \n");
                  sleep(3);
           }    
}
void *Consumer(void *data)
{
  int i;
  printf("Consumer created\n");
  for (i=0;i<1;i++)      
  {
        fputs(data,stdout);
        printf("data out \n");
  }  
  return NULL;
}

RESULTS:
main started
Producer created
abc
Segmentation fault

CERTIFIED EXPERT
Top Expert 2012
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
by golly it worked!! I just have to put some locks on it or increase the sleep.
Thank you very much!
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Yup, was just about to mention the locks. See also http://www.llnl.gov/computing/tutorials/pthreads/#Mutexes
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.