【问题标题】:Segmentation fault 11 thread program分段错误 11 线程程序
【发布时间】:2015-09-21 07:51:54
【问题描述】:

我遇到错误“Segmentation fault 11”,代码如下: 我创建了一个线程,它给参数一个结构。

我认为问题在于函数*MARIT 的声明。

对不起,我的英语不好,我是法国人。

struct parametres {
        double *T;
int N; //taille
};

void *MARIT(struct parametres parametres)
{
int *somme =0;
float *moyenne = 0;
int i;
for(i = 0; i < parametres.N; i++)
*somme = *somme + parametres.T[i];
printf("somme : %d",somme);
*moyenne = (*somme/(parametres.N+0.0));
pthread_exit(moyenne);
}`


int main(int argc, char* argv[])
{
float temps;
clock_t t1, t2;
t1 = clock();
struct parametres params;
printf("Salut à toi !\n");
printf("Donnez la taille du tableau :" );
scanf("%d", &params.N);
params.T = malloc( params.N * sizeof(double) );
int i = 0;
int nombre_aleatoire = 0;
for(i=0; i<params.N; i++){
nombre_aleatoire =  (rand() % 1000) + 1;
params.T[i]=nombre_aleatoire;
}
pthread_t arith,quadrat,cubi;
if(pthread_create(&arith, NULL, MARIT, (void*)&params) != 0)
{
perror("pthread_create");
exit(1);
}
double *result=0;
pthread_join(arith, (void**)&result);
printf("le resultat du thread : %f",result);

return 0;
}

我不知道是什么问题。

【问题讨论】:

  • void *MARIT(struct parametres parametres) { --> void *MARIT(void* data) { struct parametres parametres = *data;。另外,删除sommemoyenne 之前的所有星号(*)。
  • 警告:不兼容的指针类型将“void (struct paramètres)”传递给“void *()(void *)”类型的参数在“pthread_create”行
  • 帅哥,有一个错误:用不兼容类型'void'的表达式初始化'struct parametres'谢谢
  • 哦。试试void *MARIT(void* data) { struct parametres parametres = *(struct parametres*)data; 然后
  • 您是否删除了sommemoyenne 之前的所有星号?另外,尝试将moyenne 设为double 而不是float。不要忘记在程序末尾使用free(params.T); 释放malloced 内存,以避免内存泄漏。

标签: c multithreading algorithm pointers


【解决方案1】:

您的代码存在一些问题。

首先,MARIT的签名。它必须有一个单一的void* 参数。

其次,sommemoyenne 被声明为指针,但您不为它们分配任何内存。这就是导致段错误的原因。

第三,返回值必须是一个空指针。这意味着它必须具有指针的大小,并且它指向的值必须在调用之后仍然存在(返回 MARIT 内的自动变量的地址是不行的)。

第四,main 期望返回一个 double,所以更改 moyenne 的类型。

可以这样解决所有三个问题:

void *MARIT(void *param)
{
    struct parametres *parametres = (struct parametres*)param;
    int somme =0;
    double moyenne = 0, *ret;
    int i;
    for(i = 0; i < parametres->N; i++)
        somme = somme + parametres->T[i];
    printf("somme : %d",somme);
    moyenne = (somme/(parametres->N+0.0));
    ret = malloc(sizeof ret);
    *ret = moyenne;
    pthread_exit(ret);
}

请注意,当main 函数处理完返回值后,它应该free 它。在这种情况下,程序马上结束,释放内存是不必要的。

你还需要更改main中的printf:

printf("le resultat du thread : %f", *result);

【讨论】:

  • 谢谢,现在可以了,但是线程没有返回平均值的正确答案,它总是返回 0
  • @FlorianSL 添加了对MARIT 中第四个问题的修复(moyenne 的类型应与main 中的result 类型匹配)。另外,main 中的 printf 也有一个小改动。
【解决方案2】:
int *somme =0;

...

*somme = ... // segmentation fault here

因为您将 somme 声明为指向未分配内存的指针(此外是 NULL 指针)。解决方案:int somme = 0;

变量 moyenne 也是如此:float moyenne = 0;

【讨论】:

    【解决方案3】:
    > SYNOPSIS
    >        #include <pthread.h>
    > 
    >        int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
    >                           void *(*start_routine) (void *), void *arg);
    

    你的函数必须有一个像

    这样的签名
    void * start_routine (void *);
    

    错误的那一刻几乎所有事情都是未定义的行为。 并且在对指向 *somme 和 *moyenne 的空间进行操作之前,您必须始终为指针分配内存,因为同样的原因。虽然我完全不知道您选择使用指针而不是普通变量。

      void *MARIT(void *arg)  // change <--here
          {
              struct parametres *parametres = (struct parametres *) arg;  // change <--here
              int *somme = malloc(sizeof(int)); // change <-- here
              float *moyenne =  malloc(sizeof(float)); // change <-- here
    
              int i;
              for(i = 0; i < parametres->N; i++)  // change <--here
                  *somme = *somme + parametres->T[i];  // change <--here
              printf("somme : %d",somme);
              *moyenne = (*somme/(parametres->N+0.0));  // change <--here
              pthread_exit(moyenne);
          }`
    

    【讨论】:

    • 谢谢,现在它可以工作了,但是线程没有返回平均值的正确答案,它总是返回 0
    猜你喜欢
    • 2015-09-10
    • 2018-08-27
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    相关资源
    最近更新 更多