Ошибка сегментации pthread со связанными списками - новичок - PullRequest
2 голосов
/ 08 марта 2012

Я впервые использую pthreads. У меня проблемы, потому что иногда моя программа вызывает ошибки, а иногда - нет. В моей программе есть несколько функций, которые выполняют некоторые основные задачи (написанные на C), такие как создание связанного списка, добавление элемента в список и удаление элемента из списка. Каждая функция создает свою собственную копию списка, поэтому я не думаю, что они взаимодействуют друг с другом и, следовательно, не нуждаются в мьютексах. В любом случае, ниже приведен мой код, если у кого-то есть какие-либо идеи или если есть какие-либо «общие» ошибки начинающего пользователя.

Я запускаю каждую функцию 1000 раз параллельно, иногда seg-ошибки, иногда нет. Я заметил, что это происходит только с комбинацией этих 3 функций.

Процесс идет так: - создать тему - запускать потоки параллельно - каждый поток вызывает фиктивную функцию для выполнения задачи определенное количество раз - эта фиктивная функция также вызывает другие функции

Я думаю, что это может быть связано с использованием / распределением памяти, потому что все эти функции имеют отношение к созданию / удалению узлов связанных списков. Большое спасибо.

Вот что создает и присоединяется:

 pthread_create(&t7, NULL, (void*)&p4, (void*)var);
 pthread_create(&t8, NULL, (void*)&p5a, (void*)var);
 pthread_create(&t9, NULL, (void*)&p5b, (void*)var);
 pthread_join(t7, NULL);
 pthread_join(t8, NULL);
 pthread_join(t9, NULL);

Вот фиктивные функции:

void p4(int *nptr){
  int n = *nptr;
  // Get current time
  struct timeval t0, t1;
  gettimeofday(&t0,0);

  int i = 0;
  LIST *list = (LIST*)malloc(sizeof(LIST));
      for(i=0;i<n;i++){
    f4(list);
    deleteList(list);
  }
  // Get current time and find time elapsed
  gettimeofday(&t1,0);
  float elapsed = (t1.tv_sec-t0.tv_sec)*1000000 + t1.tv_usec-t0.tv_usec;
      printf("Successful execution of p4 in %f microseconds.\n", elapsed);
  free(list);
}
void p5a(int *nptr){
  int n = *nptr;
  LIST *list = (LIST*)malloc(sizeof(LIST));
  f4(list);
  // Get current time
  struct timeval t0, t1;
  gettimeofday(&t0,0);

  int i = 0;
      for(i=0;i<n;i++){
    f5a(list);
  }
  // Get current time and find time elapsed
  gettimeofday(&t1,0);
  float elapsed = (t1.tv_sec-t0.tv_sec)*1000000 + t1.tv_usec-t0.tv_usec;
  printf("Successful execution of p5a in %f microseconds.\n", elapsed);
}
void p5b(int *nptr){
  int n = *nptr;
  LIST *list = (LIST*)malloc(sizeof(LIST));
  f4(list);
  int i = 0;
      for(i=0;i<n;i++){
    f5a(list);
  }
  // Get current time
  struct timeval t0, t1;
  gettimeofday(&t0,0);
  for(i=0;i<n;i++){
    f5b(list);
  }
  // Get current time and find time elapsed
  gettimeofday(&t1,0);
  float elapsed = (t1.tv_sec-t0.tv_sec)*1000000 + t1.tv_usec-t0.tv_usec;
  printf("Successful execution of p5b in %f microseconds.\n", elapsed);
}

Вот функции, используемые для выполнения обычных задач:

// FUNCTION: initialize a linked list with pointers and insert a last element
void f4(LIST *L1){
  // initialize an empty linked list if L1 = null
  if(L1->head == NULL){
    NODE *n = (NODE *)malloc(sizeof(NODE));
    L1->head = n;
    L1->tail = n;
    L1->tail->next = NULL;
    n->data = 1;
  }
  // traverse the linked list to the end
  NODE *iter = L1->head;
  while(iter->next != NULL)
    iter = iter->next;
  // insert a new 2 element
  NODE *new = (NODE *)malloc(sizeof(NODE));
  new->data = 2; // arbitrary for testing
  new->next = NULL;
  iter->next = new;
  L1->tail = new;
}

// FUNCTION: add an item to the end of a list (queue)
void f5a(LIST *list){
  NODE *new = (NODE *)malloc(sizeof(NODE));
  new->data = 999;
  new->next = NULL;
  list->tail->next = new;
  list->tail = new;
}

// FUNCTION: remove an item from the beginning of a list (queue)
void f5b(LIST *list){
  NODE *remove = list->head;
  list->head = list->head->next;
  free(remove);
}

1 Ответ

3 голосов
/ 08 марта 2012

Если вы читаете malloc справочные страницы, вы можете увидеть, что не инициализирует выделенную память для 0. Итак, вы malloc память в p4, p5a и p5b функциях. После этого вы вызываете функцию f4 без инициализированных констант LIST.

В функции p4 вы проверяете действительный указатель с помощью if(L1->head == NULL), но, возможно, он не равен нулю. Таким образом, вы не выделяете память для L1->head, и после этой функции в функции f5b вы освобождаете нераспределенный указатель.

Советы:

  • Всегда инициализировать выделенные регионы.
  • Всегда проверяйте malloc возвращенные указатели
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...