首页 > 解决方案 > 分段错误:(核心转储)在尝试修改功能数组时

问题描述

我在c中努力解决这个错误,我无法理解。我正在用 c 语言制作一个石头剪刀布游戏,并带有用于练习的线程。我想在一个函数中修改两个结构元素Joueur的数组 tabJoueur。但即使我尝试显示数组的值,我也遇到了分段错误。

数组tabJueur看起来像这样

Joueur tabJoueur[2];

结构Joueur如下所示:

typedef struct
{
    int coup;
    char *nom;
    int score;
} Joueur;

这是我的主要内容:


int main()
{
    
    Joueur tabJoueur[2];
    pthread_t id[2];
    
    if (pthread_mutex_init(&cle,NULL) != 0)
    {
        printf("\n mutex init failed\n");
        return 1;
    }
    
    for (int i = 0; i < 2 ; i++)
    {
        Joueur *args = (Joueur*)malloc(sizeof(Joueur));
        args = &tabJoueur[i];
        args->nom = (char*)malloc(sizeof(char));
        args->coup = -1;
        args->score = 0;
        pthread_create(&id[i],NULL,functionJoueur,args);
    }
    
    while(tabJoueur[0].score < 3  || tabJoueur[1].score < 3)
    {
        if (tabJoueur[0].coup != -1 && tabJoueur[1].coup != -1)
        {
            if (pthread_mutex_lock(&cle) == 0)
            {
                //Joueur (*pJoueur)[2] = malloc(sizeof(Joueur)*2);
                //pJoueur = &tabJoueur;
                jugeChifoumi(&tabJoueur);
                //free(pJoueur);
                
                for (int i = 0 ; i < 2 ; i++)
                {
                    tabJoueur[i].coup = -1;
                }
                
                pthread_mutex_unlock(&cle);
            }
        }
    }
    
    for (int i = 0 ; i < 2 ; i++)
    {
        if (tabJoueur[i].score == 3)
        {
            printf("Victoire de %s", tabJoueur[i].nom);
        }
        printf("%s Dit au revoir", tabJoueur[i].nom);
        free(tabJoueur[i].nom); // on libère la mémoire du nom
    }
    
    for (int i = 0 ; i < 2; i++)
    {
        pthread_cancel(id[i]); // on détruit les threads
    }
    pthread_mutex_destroy(&cle); // on détruit la cle mutex
    
    return 1;
}

当 main 获取互斥锁时,问题发生在 while 循环中。在这里,我给出了一个名为 jugeChifoumi 的函数,看起来像这样。

void jugeChifoumi(Joueur (*tabCoup)[2])
{
    printf("%s joue %d  et %s joue %d.\n", tabCoup[0]->nom, tabCoup[0]->coup, tabCoup[1]->nom, tabCoup[1]->coup);
    int resultat = tabCoup[0]->coup - tabCoup[1]->coup;
    if (resultat == -2 || resultat == 1)
    {
        tabCoup[0]->score = tabCoup[0]->score + 1; // on rajoute 1 dans le score du joueur 1
        printf("%s a gagné! %d points contre %d points.\n", tabCoup[0]->nom, tabCoup[0]->score, tabCoup[1]->score);
    }
    else if (resultat == -1 || resultat == 2)
    {
        tabCoup[1]->score = tabCoup[1]->score + 1; // on rajoute 1 dans le score du joueur 2
        printf("%s a gagné! %d points contre %d points.\n", tabCoup[1]->nom, tabCoup[0]->score, tabCoup[1]->score);
    }
    else
    {
        printf("Match nul\n");
    }
}

即使我尝试访问数组的元素,我也相信我进入了一个被禁止的内存。但我不明白它为什么这样做,我想我可以修改我的数组 tabJueur,只需将他的地址放在 (&) 上,然后通过函数参数中的指针修改它。我可以理解这是指针的基本知识,但是在看到这么多给出不同解决方案的帖子之后,我开始感到困惑。

例如,有些人建议int *array和其他人建议int array[size],其他人谈论使用这样的指针:

Joueur (*p)[2] = malloc(sizeof(Joueur)*2);
p = tabJoueur;
jugeChifoumi(p);

但我不明白为什么。一些提示会非常好。提前致谢。

标签: cpointerssegmentation-faultpthreads

解决方案


问题出在jugeChifoumi和对它的调用上。C 中的数组已经通过引用传递。

您应该更改以下内容:

void jugeChifoumi(Joueur (*tabCoup)[2])
{
    printf("%s joue %d  et %s joue %d.\n", tabCoup[0]->nom, tabCoup[0]->coup, tabCoup[1]->nom, tabCoup[1]->coup);
    int resultat = tabCoup[0]->coup - tabCoup[1]->coup;
    if (resultat == -2 || resultat == 1)
    {
        tabCoup[0]->score = tabCoup[0]->score + 1; // on rajoute 1 dans le score du joueur 1
        printf("%s a gagné! %d points contre %d points.\n", tabCoup[0]->nom, tabCoup[0]->score, tabCoup[1]->score);
    }
    else if (resultat == -1 || resultat == 2)
    {
        tabCoup[1]->score = tabCoup[1]->score + 1; // on rajoute 1 dans le score du joueur 2
        printf("%s a gagné! %d points contre %d points.\n", tabCoup[1]->nom, tabCoup[0]->score, tabCoup[1]->score);
    }

...对此使用不同的声明并将“->”更改为“。” 到处。

void jugeChifoumi(Joueur tabCoup[2])
{
    printf("%s joue %d  et %s joue %d.\n", tabCoup[0].nom, tabCoup[0].coup, tabCoup[0].nom, tabCoup[1].coup);
    int resultat = tabCoup[0].coup - tabCoup[1].coup;
    if (resultat == -2 || resultat == 1)
    {
        tabCoup[0].score = tabCoup[0].score + 1; // on rajoute 1 dans le score du joueur 1
        printf("%s a gagné! %d points contre %d points.\n", tabCoup[0].nom, tabCoup[0].score, tabCoup[1].score);
    }
    else if (resultat == -1 || resultat == 2)
    {
        tabCoup[1].score = tabCoup[1].score + 1; // on rajoute 1 dans le score du joueur 2
        printf("%s a gagné! %d points contre %d points.\n", tabCoup[1].nom, tabCoup[0].score, tabCoup[1].score);
    }

您应该从以下位置更改呼叫:

            jugeChifoumi(&tabJoueur);

至:

            jugeChifoumi(tabJoueur);

您在 main() 中将 tabJouer 声明为局部变量就可以了。


推荐阅读