在Linux下运行C++代码时出现分段错误

von4xj4u  于 2022-10-23  发布在  Linux
关注(0)|答案(1)|浏览(166)

我正在尝试实现一个程序,在这个程序中,该程序从用户在命令行中获取数字,并在线程中计算他们的平均值,并在Main中打印该平均值。但总会出现分段错误。


# 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;
}

当我在另一台PC上运行相同的代码时,它运行得很好。

hi3rlvi2

hi3rlvi21#

在这种情况下,我会开始使用像gdb这样的调试器来调试代码。就个人而言,我发现this很有帮助。但是只要找到一个适合你需要的教程就行了。
第一步是使用调试信息编译代码。就GCC而言,这意味着设置-g旗帜。我是如何编译您的代码的:

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

在本例中,在core file的帮助下,gdb输出如下所示:

Program terminated with signal SIGSEGV, Segmentation fault.

# 0  0x0000000000401260 in avg (ar=0x7ffdb2179490) at main.cpp:22

22  *avg1=sum/size;

基本上,您的程序试图访问不是它要访问的内存。所以操作系统停止了它,并使程序崩溃。又名Seg-Fault error
此外,我们可以看到,在未编译的代码中,程序崩溃的时间点转换为line 22 in main.cpp
正如注解中已经提到的,float *avg1;指向内存中的一个随机地址,因为它没有被初始化。这个地址不是为您“保留”的可能性非常高:d*avg1=sum/size;然后尝试将计算出的值写入该随机地址,从而导致Seg-错误错误。

可能的解决方案

直接的做法是在内存中保留一些空间,并将该内存的地址保存在浮动指针avg1中。人们可以通过使用malloc()来做到这一点。Wikipedia

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

相关问题