为什么我的C程序中不断出现分段错误

时间:2019-03-20 15:24:32

标签: c

我一直在尝试在C上实现线程同步。但是,当我调用希望线程执行的函数时,我总是遇到分段错误。因此,任何人都可以提出针对该问题的解决方案?

这是我的代码

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

#define N 5
#define M 3
#define LEFT (robot_id - 1) % N
#define RIGHT (robot_id + 1) % N

pthread_t robots_id[N];
sem_t simulations[M];
pthread_mutex_t sever_mutex;

void Learning(int robot_id)
{
    printf("learning robot = %d\n", robot_id);
}

void *robotAct(void *id)
{
    int *robot_id = id;
    printf("robot id = %d\n", robot_id);
    Learning(*robot_id);
}

int main(int argc, char *argv[])
{
    int E, T;

    E = atoi(argv[1]);
    T = atoi(argv[2]);

    printf("Initializing Robot!\n");

    //Initializes the simulations
    for (int i = 0; i < M; i++)
    {
        sem_init(&simulations[i], 0, 0);
    }

    //Initializes the robots
    for (int i = 0; i < N; i++)
    {
        printf("Robot %d is created\n", i + 1);
        pthread_create(&robots_id[i], NULL, robotAct, (void *)i + 1);
    }

    sleep(T);

    printf("Terminating Robots\n");
    for (int i = 0; i < N; i++)
    {
        pthread_cancel(robots_id[i]);
    }
    printf("Termination is completed!\n");
    printf("-------Report-------------\n");
    //getReport();
    return 0;
}

这是我不断得到的结果

Initializing Robot!
Robot 1 is created
Robot 2 is created
Robot 3 is created
robot id = 1
robot id = 2
Robot 4 is created
robot id = 3
[1]    54477 segmentation fault  ./project 5 10

1 个答案:

答案 0 :(得分:1)

主要问题在我的评论中进行了解释:

  

您没有将有效的指针传递给线程函数。在printf()的{​​{1}}调用中,您几乎可以避免滥用它;您着重在取消引用无效非指针的robotAct()的调用中无法摆脱它。

一种解决方案是在主程序中创建一个包含机器人ID号(Learning())的整数数组。然后,初始化每个元素并将int id[N];传递给&id[i]

您不应打印pthread_create()格式的地址(即使它在32位系统上运行;在64位系统上也不运行)。正确的技术是使用%d格式化地址。或者,在这种情况下,请使用%p打印整数而不是地址。

以下代码对原始代码的适应性很小,并且尚未进行编译或测试(更改后的行可能有问题):

*robot_id

避免使用#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> #define N 5 #define M 3 #define LEFT (robot_id - 1) % N #define RIGHT (robot_id + 1) % N pthread_t robots_id[N]; sem_t simulations[M]; pthread_mutex_t sever_mutex; void Learning(int robot_id) { printf("learning robot = %d\n", robot_id); } void *robotAct(void *id) { int *robot_id = id; printf("robot id = %d\n", *robot_id); // Changed Learning(*robot_id); return 0; // Added } int main(int argc, char *argv[]) { int E, T; int id[N]; // Added E = atoi(argv[1]); T = atoi(argv[2]); printf("Initializing Robot!\n"); //Initializes the simulations for (int i = 0; i < M; i++) { sem_init(&simulations[i], 0, 0); } //Initializes the robots for (int i = 0; i < N; i++) { printf("Robot %d is created\n", i + 1); id[i] = i + 1; // Added pthread_create(&robots_id[i], NULL, robotAct, &id[i]); // Changed } sleep(T); printf("Terminating Robots\n"); for (int i = 0; i < N; i++) { pthread_cancel(robots_id[i]); } printf("Termination is completed!\n"); printf("-------Report-------------\n"); //getReport(); return 0; } 结束线程;线程应在控制下终止。例如,您可能在主线程中设置了一个标志,以指示线程应该停止,并且它们会定期检查。通常,pthread_cancel()用于清理完成的线程。

有关将来的帖子,请阅读有关如何创建MCVE(Minimal, Complete, Verifiable Example)的信息。显示的代码中有部分与问题无关—例如,互斥量和信号量并未真正使用。