尝试删除节点会导致seg错误

时间:2013-11-26 20:26:10

标签: c segmentation-fault nodes doubly-linked-list

我正在尝试创建一个多线程,用于将元素插入到命令文件的双向链表中但是当它尝试从列表的开头删除节点时会抛出一个seg错误,我无法确定原因。

#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h> 
#include <sys/types.h> 
#include <semaphore.h>
#define true 1
#define false 0

typedef int bool;

typedef struct commandnode  //struct for command list
{
  struct commandnode *prevcommand;
  char *a;
  int key;
  struct commandnode *nextcommand;
  pthread_mutex_t commandlock;
} commandnode;

typedef struct Node
{
  struct Node *prev;
  int n;
  struct Node *next;
  pthread_mutex_t lock;
} Node;

typedef struct List
{
  int size;
  commandnode *head;
  commandnode *tail;
  Node *tailer;
  Node *header;
} List;

int search(int);
void create(int);
void insert(List, int);
void delete(List, int);
void printList(List);
void printEle(List, int);

void createcommand(char[], int);
void insertcommand(List, char[], int);
void printcommandList();
commandnode removecommand(List);

int nodecount = 0;
sem_t fill;
sem_t empty;
int emptyed = 5;
int filled = 0;

List* buffer;
List* line;

void* doSomeThing(void *arg)
{
  int value, i;
  char *command;
  commandnode *tempcommand = malloc(sizeof(commandnode));
  for (i = 0; i < 5; i++)
  {
    sem_wait(&fill);
    //printcommandList(*buffer);
    //printf("|");
    *tempcommand = removecommand(*buffer);
    //command=tempcommand->a;
    //value=tempcommand->key;
    sem_post(&empty);

  }
  return 0;
}

int main(int paramcount, char* paramstr[])
{
  FILE *infile;
  pthread_t *thread;
  int workers = 1;
  int err, slot, i, k;
  sem_init(&empty, 0, workers);
  sem_init(&fill, 0, 0);
  if (paramcount != 1)
  {
    printf("Incorrect number of parameters");
    return 1;
  }

  thread = (pthread_t *) malloc(workers * sizeof(pthread_t)); //creating theads

  buffer = calloc(1, sizeof(List));
  buffer->head = calloc(1, sizeof(commandnode));
  buffer->tail = calloc(1, sizeof(commandnode));
  buffer->head->nextcommand = buffer->tail;
  buffer->tail->prevcommand = buffer->head;

  line = calloc(1, sizeof(List));
  line->header = calloc(1, sizeof(Node));
  line->tailer = calloc(1, sizeof(Node));
  line->header->next = line->tailer;
  line->tailer->prev = line->header;

  for (i = 0; i < 1; i++)
  {
    slot = i;
    err = pthread_create(&(thread[i]), NULL, &doSomeThing, &slot);
    if (err != 0)
      printf("\ncan't create thread :[%s]", strerror(err));
    //else
    //printf("thread created");
  }

  infile = fopen("fscanftest.txt", "r");

  if (infile == NULL )
  {
    printf("Error opening file.\n");
    return 2;
  }

  int inputs = 0;
  int key;
  //while(inputs==0){ 
  for (i = 0; i < 5; i++)
  {
    char command[40];
    char *commands = malloc(sizeof(char) * 1024);
    fscanf(infile, "%s", command);
    strcpy(commands, command);
    /*if(strcmp(command,"exit")==0){
     key=0;
     for(k=0;k<workers;k++){
     sem_wait (&empty);
     insertcommand(*buffer,commands,key);        
     sem_post(&fill);
     }
     inputs=1;
     }
     else{*/
    if (strcmp(command, "insert") == 0 || strcmp(command, "delete") == 0
        || strcmp(command, "read") == 0)
    {
      fscanf(infile, "%d", &key);
    }
    else
    {
      key = 0;
    }
    sem_wait(&empty);
    insertcommand(*buffer, commands, key);
    sem_post(&fill);
    //sem_getvalue(&empty,&k);
    //printf("%d",k);
    //sem_getvalue(&fill,&k);
    //printf("(%d)",k);

    //}

  }
  //printcommandList(*buffer);

  int c;
  for (c = 0; c < 1; c++)
    pthread_join(thread[c], NULL );
  return 1;
}

void insertcommand(List list, char* command, int sendkey)
{
  commandnode *tempcommand = malloc(sizeof(commandnode));

  pthread_mutex_lock(&list.tail->commandlock);
  pthread_mutex_lock(&list.tail->prevcommand->commandlock);

  tempcommand->prevcommand = list.tail->prevcommand;
  tempcommand->nextcommand = list.tail;
  tempcommand->prevcommand->nextcommand = tempcommand;
  list.tail->prevcommand = tempcommand;
  tempcommand->a = command;
  tempcommand->key = sendkey;

  pthread_mutex_unlock(&list.tail->commandlock);
  pthread_mutex_unlock(&list.tail->prevcommand->prevcommand->commandlock);

}
commandnode removecommand(List list)
{

  commandnode *tempcommand = malloc(sizeof(commandnode));
  pthread_mutex_lock(&list.head->commandlock);
  pthread_mutex_lock(&list.head->nextcommand->commandlock);
  pthread_mutex_lock(&list.head->nextcommand->nextcommand->commandlock);

  tempcommand = list.head->nextcommand;
  //printf(" %s %d ",tempcommand->a,tempcommand->key); 
  list.head->nextcommand = tempcommand->nextcommand; // found the seg falut happens here
  list.head->nextcommand->prevcommand = list.head;
  list.head->nextcommand->prevcommand = list.head;

  pthread_mutex_unlock(&list.head->commandlock);
  pthread_mutex_unlock(&list.head->nextcommand->commandlock);
  pthread_mutex_unlock(&list.head->nextcommand->nextcommand->commandlock);

  return *tempcommand;
}

void printcommandList(List list)
{
  commandnode *tempcommand = malloc(sizeof(commandnode));
  //pthread_mutex_lock(&list.head->commandlock);
  // pthread_mutex_lock(&list.head->nextcommand->commandlock);

  tempcommand = list.head->nextcommand;

  //pthread_mutex_unlock(&list.head->commandlock);

  while (tempcommand->nextcommand != list.tailer)
  {
    printf(" %s ", tempcommand->a);
    printf(" %d ", tempcommand->key);

    //  pthread_mutex_lock(&tempcommand->nextcommand->commandlock);
    tempcommand = tempcommand->nextcommand;
    //  pthread_mutex_unlock(&tempcommand->prevcommand->commandlock);   
  }
  //pthread_mutex_unlock(&tempcommand->prevcommand->nextcommand->commandlock);

}

1 个答案:

答案 0 :(得分:0)

你malloc tempcommand,然后泄漏它:

commandnode *tempcommand = malloc(sizeof(commandnode)); // **malloc****
pthread_mutex_lock(&list.head->commandlock);
pthread_mutex_lock(&list.head->nextcommand->commandlock);
pthread_mutex_lock(&list.head->nextcommand->nextcommand->commandlock);

tempcommand=list.head->nextcommand; // **leak**
//printf(" %s %d ",tempcommand->a,tempcommand->key); 
list.head->nextcommand=tempcommand->nextcommand; // found the seg falut happens here

seg错误可能是因为tempcommand为0.你可能不希望泄漏所在的分配。