在 Ubuntu WSL 中使用 gcc 编译 .c 和头文件时遇到问题

Trouble compiling .c and header files with gcc in Ubuntu WSL

我正在尝试使用多线程编译一些 C 代码,由于某种原因,当我尝试 运行:

时,Ubuntu WSL 终端出现分段错误

gcc -o mashu concurrent_list.c concurrent_list.h

我正在尝试 运行 的文件如下:

concurrent_list.c:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "concurrent_list.h"

struct node {
  int value;
  node* next;
  pthread_mutex_t* lock;
  // add more fields
};

struct list {
  // add fields
  node* head;
  pthread_mutex_t* lock;
};

void print_node(node* node)
{
  // DO NOT DELETE
  if(node)
  {
    printf("%d ", node->value);
  }
}

list* create_list()
{
  // add code here
  list* l = malloc(sizeof(list));
  if(l == NULL){
    printf("malloc error");
  }
  l->head = NULL;
  l->head->next = NULL;
  if(pthread_mutex_init(l->lock, NULL) != 0){
     printf("mutex init failed\n");
  }
  if(pthread_mutex_init(l->head->lock, NULL) != 0){
    printf("mutex init failed\n");
  }
  return l;
}

void delete_list(list* list)
{
  // add code here
  pthread_mutex_lock(list->lock);
  node* head = list->head;
  node* next = head->next;
  while(next->next != NULL){
    free(head);
    next = next->next;
    head = next;
  }
  pthread_mutex_unlock(list->lock);
  free(list);
}

void insert_value(list* list, int value)
{
  // add code here

  // if the list is empty
  pthread_mutex_lock(list->lock);
  if(list->head == NULL){
    list->head->value = value;
    pthread_mutex_unlock(list->lock);
  }
  else{
    // init newnode
    node* newNode = malloc(sizeof(node));
    if(!newNode){
      printf("malloc failed\n");
    }
    newNode->value = value;
    newNode->next = NULL;
    if(pthread_mutex_init(newNode->lock, NULL) != 0){
      printf("mutex init failed\n");
    }

    node* curr = list->head;
    // lock the list and the first node 
    pthread_mutex_lock(curr->lock);
    if(curr->next == NULL){ // first and only node at the start of a list
      if(curr->value > value){  // insert the newnode at the beggining
        list->head = newNode;
        newNode->next = curr;
      }else{
        curr->next = newNode;
      }
      pthread_mutex_unlock(list->lock);
      pthread_mutex_unlock(curr->lock);
      // finished the insert
    }
    else{
      node* prev = curr;
      curr = curr->next;
      pthread_mutex_unlock(list->lock);
      pthread_mutex_lock(curr->lock);
      while(curr->value < value && curr->next != NULL){
        pthread_mutex_unlock(prev->lock);
        prev = curr;
        curr = curr->next;
        pthread_mutex_lock(curr->lock);
      }
      if(curr->next == NULL){
        curr->next = newNode;
      }else{
        prev->next = newNode;
        newNode->next = curr;
      }
      pthread_mutex_unlock(prev->lock);
      pthread_mutex_unlock(curr->lock);
    }
  }
}

void remove_value(list* list, int value)
{
  // add code here
  
  
  
}

void print_list(list* list)
{
  // add code here
  node* curr = list->head;
  pthread_mutex_lock(list->lock);
  if(curr != NULL){
    pthread_mutex_unlock(list->lock);
    while(curr != NULL){
      pthread_mutex_lock(curr->lock);
      print_node(curr);
      curr = curr->next;
      pthread_mutex_unlock(curr->lock);
    }
  }
  printf("\n"); // DO NOT DELETE
}

void count_list(list* list, int (*predicate)(int))
{
  int count = 0; // DO NOT DELETE

  // add code here

  printf("%d items were counted\n", count); // DO NOT DELETE
}

int main(){
  list* l = create_list();
  printf("1\n");
  insert_value(l,6);
  printf("2\n");
  insert_value(l,12);
  insert_value(l,3);
  insert_value(l,19);
  insert_value(l,8);
  printf("3\n");
  print_list(l);
  printf("4\n");
  delete_list(l);
}

concurrent_list.h:

typedef struct node node;
typedef struct list list;

list* create_list();
void delete_list(list* list);
void print_list(list* list);
void insert_value(list* list, int value);
void remove_value(list* list, int value);
void count_list(list* list, int (*predicate)(int));

编译时抛出的错误是:

Segmentation fault

我是在访问非法内存,没有正确编译还是我使用了错误的互斥线程?

如有任何帮助,我们将不胜感激。

create_list():

    如果 malloc 失败,
  1. l->head = NULL 将出现段错误。除了打印之外,您可能还想 return NULL;
  2. 当您将 l->head 设置为 NULL 时,
  3. l->head->next = NULL; 将始终出现段错误
  4. pthread_mutex_init(l->head->lock, NULL) 将始终出现段错误,因为 l->headNULL

insert_value():

    如果 list->headNULL
  1. list->head->value = value; 将出现段错误。您甚至可以确保它与 if 语句一起使用。

当您在修改时锁定列表(并且您至少需要为头部更改执行此操作)我取消了节点锁定。在 print_list() 中内联 print_node(),因为前者要求调用者获取一个有风险的锁。固定 create_list() 以上。简化 delete_list()。固定(按上述)和简化 insert_value()。删除了死代码 remove_value():

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

typedef struct node node;
struct node {
    int value;
    node *next;
};
typedef struct list list;
struct list {
    node *head;
    pthread_mutex_t *lock;
};

list* create_list();
void delete_list(list* list);
list *insert_value(list* list, int value);
void print_list(list* list);

list* create_list() {
    list* l = malloc(sizeof(*l));
    if(!l) {
        printf("malloc error");
        return NULL;
    }
    l->head = NULL;
    if(pthread_mutex_init(l->lock, NULL) != 0) {
        printf("mutex init failed\n");
    }
    return l;
}

void delete_list(list *l) {
    pthread_mutex_lock(l->lock);
    while(l->head) {
        node *n = l->head;
        l->head = l->head->next;
        free(n);
    }
    free(l);
    pthread_mutex_unlock(l->lock);
}


list *insert_value(list *l, int value) {
    node* newNode = malloc(sizeof(node));
    if(!newNode){
        printf("malloc failed\n");
        return NULL;
    }
    newNode->value = value;

    // head
    pthread_mutex_lock(l->lock);
    if(!l->head || value < l->head->value){
        newNode->next = l->head;
        l->head = newNode;
        pthread_mutex_unlock(l->lock);
        return l;
    }
    // non-head
    node *n = l->head;
    for(; n->next && value >= n->next->value; n = n->next);
    newNode->next = n->next;
    n->next = newNode;
    pthread_mutex_unlock(l->lock);
    return l;
}

void print_list(list *l) {
    pthread_mutex_lock(l->lock);
    for(node *n = l->head; n; n = n->next) {
        printf("%d ", n->value);
    }
    pthread_mutex_unlock(l->lock);
    printf("\n");
}

int main(){
    list* l = create_list();
    printf("1\n");
    insert_value(l, 6);
    printf("2\n");
    insert_value(l,12);
    insert_value(l,3);
    insert_value(l,19);
    insert_value(l,8);
    printf("3\n");
    print_list(l);
    printf("4\n");
    delete_list(l);
}

输出为:

1
2
3
3 6 8 12 19 
4