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

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

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

  1. # include<iostream>
  2. # include<pthread.h>
  3. # include <unistd.h>
  4. using namespace std;
  5. void *avg(void* ar )
  6. {
  7. int *p=(int *) ar;
  8. int size=*p;
  9. size--;
  10. float sum=0;
  11. for(int i=0;i<size;i++)
  12. {
  13. p++;
  14. int y=*p;
  15. sum=sum+y;
  16. }
  17. float *avg1;
  18. *avg1=sum/size;
  19. float *rt=avg1;
  20. pthread_exit((void *) rt);
  21. }
  22. int main(int arg,char**argc )
  23. {
  24. int n=arg;
  25. int arr[n];
  26. arr[0]=n; //storing aaray size in first index of array
  27. for(int i=1;i<n;i++)
  28. {
  29. int x=atoi(argc[i]);
  30. arr[i]=x;
  31. }
  32. for(int i=1;i<n;i++)
  33. cout<<arr[i]<<endl;
  34. pthread_t t1,t2;
  35. int x=pthread_create(&t1,NULL,&avg,(void*)arr);
  36. if(x!=0)
  37. {
  38. cout<<"Error in Creating Thread\n";
  39. exit(EXIT_FAILURE);
  40. }
  41. float *rt1;
  42. pthread_join(t1,(void**)&rt1);
  43. cout<<"AVG:"<<*rt1;
  44. return 0;
  45. }

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

hi3rlvi2

hi3rlvi21#

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

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

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

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

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

可能的解决方案

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

  1. float *avg1 = (float *) malloc(sizeof(float));
  2. *avg1=sum/size;
  3. float *rt=avg1;
  4. pthread_exit((void *) rt);
展开查看全部

相关问题