-1

I am trying to implement a program in which the program takes numbers from user in command line and calculate their average in the thread and prints that average in main. But always getting segmentation fault error.

#include<iostream>
#include<pthread.h>
#include <unistd.h>
using namespace std;

void *avg(void* ar )
{
    int *p=(int *) ar;
    int size=*p;
    size--;
    float sum=0;
    for(int i=0;i<size;i++)
    {
        p++;
        int y=*p;
        sum=sum+y;
    }

    float *avg1;
    *avg1=sum/size;
    float *rt=avg1;
    pthread_exit((void *) rt);

}

int main(int arg,char** argc )
{
    int n=arg;
    int arr[n];
    arr[0]=n;  //storing aaray size in first index of array
    for(int i=1;i<n;i++)
    {
        int x=atoi(argc[i]);
        arr[i]=x;
    }

    for(int i=1;i<n;i++)
        cout<<arr[i]<<endl;
    pthread_t t1,t2;

    int x=pthread_create(&t1,NULL,&avg,(void*)arr);
    if(x!=0)
    {

        cout<<"Error in Creating Thread\n";
        exit(EXIT_FAILURE);

    }

    float *rt1;
    pthread_join(t1,(void**)&rt1);
    cout<<"AVG:"<<*rt1;
    return 0;
}

When i ran the same code on another pc, it was working fine.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • The conventional names for the arguments to `main()` are `(int argc, char **argv)` – Barmar Oct 21 '22 at 18:43
  • Bugs are like that. In this case it could be as simple as `n` specifying an array too large to fit on the stack. On one machine it works because of a larger stack, and on another machine it fails because it's stack is too small. – user4581301 Oct 21 '22 at 18:43
  • Hmmm. Given where `n` comes from too-large an array is extremely unlikely. – user4581301 Oct 21 '22 at 18:45
  • 2
    `int arr[n];` is not valid C++, have you tried using a debugger to see why the segfault happens? – Quimby Oct 21 '22 at 18:45
  • 4
    `float *avg1; *avg1=sum/size;`. Undefined; `avg1` doesn't point to anything, so you can't assign to the thing it points to. I suspect there are more problems, but I haven't read the code closely enough to find them since you seem to be having trouble locating your keyboard's spacebar. – Miles Budnek Oct 21 '22 at 18:46
  • Your code with a few more options turned on to help find errors: https://godbolt.org/z/oP1MPne3j . It instantly finds the error pointed out by Miles with both a compiler warning (never ignore the warnings) and a report of a runtime error over the uninitialized pointer. – user4581301 Oct 21 '22 at 18:50

1 Answers1

0

in such cases, I would start to debug my code with a debugger like gdb. Personally, I found this helpful. But just find a tutorial that fits your needs.

First step would be to compile the code with debuging information. In the case of gcc, that means setting the -g flag. How I compiled your code:

% g++ -Wall -Wextra -g -o a.out main.cpp 

In your case the gdb output, with the help of the core file, looks like this:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000000000401260 in avg (ar=0x7ffdb2179490) at main.cpp:22
22  *avg1=sum/size;

Basically your program tried to access memory that wasn't it's to access. So the OS stopped it and crashed the program. aka Seg-Fault error

Additionally, we can see that the point at which your program crashed translates to line 22 in main.cpp in your uncompiled code.

As already mentioned in the comments float *avg1; points to a random address in memory because it's not initialized. The probability that this address is not "reserved" for you is pretty high :D *avg1=sum/size; then tries to write the calculated value at that random address, thus causing a Seg-Fault error.

possible Solutions

The straight forward thing to do would be to reserve some space in memory and save the address to that memory in the float pointer avg1. One can do that by using malloc(). Wikipedia

    float *avg1 = (float *) malloc(sizeof(float));
    *avg1=sum/size;
    float *rt=avg1;
    pthread_exit((void *) rt);

  • Note: in C++ `malloc` is a tool that should be reached for rarely, and only after automatic allocation, a library container, a smart pointer, and `new` have all been tried and found wanting. This almost never happens – user4581301 Oct 22 '22 at 14:33