2013-12-10 3 views
1

Я опубликовал это ранее сегодня, но я понял, что раньше ставил старое издание своего несвязанного кода, но этот код компилируется в gcc, мне нужно создать пробуждение в отеле который, когда генерируется новый аварийный сигнал, распечатывается, помещается правильно в список (сначала по порядку ближайшего сигнала тревоги), а затем выводится время вызова.Данные, заменяемые имитированным звонком по телефону

Проблема заключается в том, что при вставке узлов (insertNode()) добавленныйNode при добавлении в список перезаписывает голову и записывает в следующий узел вместо того, чтобы просто записывать alarmData в головной узел.

#include <stdlib.h> 
#include <stdio.h> 
#include <assert.h> 
#include <pthread.h> 
#include <time.h> 
#include <signal.h> 

#define ETIMEDOUT 110 

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 

const int MAX_ROOM_NUMBER = 1000; 
const int MAX_SECOND = 100; 
static int NotCancelled = 0; 
int REGISTER = 0; 

typedef struct wakeUp 
{ 

    int room; //Structure that has the room to awake 
    time_t alarm;//and the time that the room wishes to wake 
}wakeUp; 

typedef struct node 
{ 

    wakeUp awake; // Nodes used as a list to hold the of alarms ordered earliest node first 
    struct node* nextNode;// it contains the struct WakeUp and a pointer to the next node 
}node; 

node * AlarmData; 
pthread_t insert,wakeRoom; 


static void * 
printAlarmsData(node* first) 
{ 
    if (first == NULL) 
    { 
    printf("This List Of Alarms is empty!\n"); 
    return; 
    } 
    else 
    { 
    node* p = first; 
    int count = 0; 
    while (p != NULL) 
    { 
     printf("%d %s, \n", p->awake.room, ctime(&p->awake.alarm)); 
     count++; 
     if (p->nextNode == NULL || count == 10) 
     { 
     return; 
     } 

    } 
    } 
} 

static int 
removeAlarm(wakeUp * first) 
{ //When the alarm occurs remove the first Node 

    pthread_mutex_lock(&lock); // Hold the lock 

    time_t current_time; 
    time(&current_time); 

    if (current_time < first->alarm) 
    { 
    printf("Waiting...\n"); 
    pthread_cond_signal(&cond); 
    pthread_mutex_unlock(&lock); 
    return 0; 
    } 
    else 
    { 
    AlarmData = AlarmData->nextNode; 
    pthread_cond_signal(&cond); 
    pthread_mutex_unlock(&lock); 
    return 1; 
    } 
} 

int 
length(node* first) 
{ // Shows how many Alarms are left. 
    node* p = first; 
    int count = 0; 

    while (p != NULL) 
    { 
    count++; 
    p = p->nextNode; 

    } 
    return count; 
} 

// insert Node function 

void 
insertNode(node* addedNode) 
{     //this method here 
    pthread_mutex_lock(&lock);   // head keeps getting overwritten instead 
    node *head, *temp, *prev, *next;    // of writing data into AlarmData 
    temp = (node*) malloc(sizeof(node)); 
    head = AlarmData; 
    temp = addedNode; 
    temp->nextNode = NULL; 
    if (!head) 
    { 
    printf("Head is null\n"); 
    head = temp; 
    } 
    else 
    { 
    printf("Head is not null\n"); 
    prev = NULL; 
    next = head; 
    printf("Existing Data Showing Below\n"); 
    while (next && (next->awake.alarm) <= (addedNode->awake.alarm)) 
    { 
     printf("----> %d %s\n", next->awake.room, ctime(&next->awake.alarm)); 
     prev = next; 
     next = next->nextNode; 
    } 
    if (!next) 
    { 
     prev->nextNode = temp; 
    } 
    else 
    { 
     if (prev) 
     { 
     temp->nextNode = prev->nextNode; 
     prev->nextNode = temp; 
     } 
     else 
     { 
     temp->nextNode = head; 
     head = temp; 
     } 
    } 

    } 
    AlarmData = (node*) malloc(sizeof(node)); 
    AlarmData = head; 
    pthread_cond_signal(&cond); 
    pthread_mutex_unlock(&lock); 
} 

static void 
cancelHandler(int signo) 
{ 
    printf("\nAre you sure you want to exit this program Y/N:"); 
    char input; 
    scanf("%c", &input); 
    if (input == 'y') 
    { 
    NotCancelled = 1; 
    wakeUp n = AlarmData->awake; 
    while (AlarmData != NULL) 
    { 
     removeAlarm(&n); 
    } 

    pthread_cancel(insert); 

    pthread_cancel(wakeRoom); 

    pthread_join(insert, NULL); 
    printf("Goodbye from insert thread"); 
    pthread_join(wakeRoom, NULL); 
    printf("Goodbye from wakeUp thread"); 
    printf("Program Exited"); 
    return; 
    } 
} 

static void * 
insertHandler() 
{ 
    printf("\nwent to insertHandler\n"); 
    while (NotCancelled == 0) 
    { 
    sleep(rand() % 2); 
    int roomId = rand() % MAX_ROOM_NUMBER + 1; 

    time_t timeToWake = time(NULL) + (rand() % MAX_SECOND + 1); 
    wakeUp wake; 
    wake.room = roomId; 
    wake.alarm = timeToWake; 

    node newAlarm; 
    newAlarm.awake = wake; 
    REGISTER++; 
    insertNode(&newAlarm); 

    printf("After Registering:\t%d\t%s\n\n", roomId, ctime(&timeToWake)); 
    } 
    return; 
} 
static void * 
wakeRoomHandler() 
{ 
    printf("\nwent to wakeRoomHandler\n"); 
    while (NotCancelled == 0) 
    { 
    sleep(rand() % 15); 

    if (AlarmData != NULL) 
    { 
     wakeUp wake = AlarmData->awake; 
     time_t timeToWake = AlarmData->awake.alarm; 
     int roomId = AlarmData->awake.room; 
     printf("Checking:\t%d\t%s\n\n", roomId, ctime(&timeToWake)); 
     int status = removeAlarm(&wake); 
     if (status == 1) 
     { 
     printf("Wake Up:\t%d\t%s\n\n", roomId, ctime(&timeToWake)); 
     } 
    } 
    } 
    return; 
} 

int 
main(void) 
{ 
    sigset_t set; 
    sigemptyset(&set); 
    sigaddset(&set, SIGINT); 
    sigset(SIGINT, cancelHandler); 
    pthread_create(&insert, NULL, insertHandler, NULL); 
    pthread_create(&wakeRoom, NULL, wakeRoomHandler, NULL); 
    while (1) 
    { 
    } 

    return (0); 

} 
+1

BTW: объявление 'node * AlarmData;' в глобальном пространстве обычно инициализируется на 0. Лучше быть явным с 'node * AlarmData = NULL;' – chux

+1

у вас есть утечка памяти, когда temp = node вы удаляете указатель, который вы создали с помощью malloc, и сохраните указатель, который вы передали в качестве параметра. вам нужно * temp = * node; для копирования данных –

+1

После 'AlarmData = head;' поля 'head' не установлены. – chux

ответ

0

Вы выделили память для температуры, но в третьей строке функции inserNode вы назначили адрес addedNode в темп.

В конце функции insertNode вы сделали то же самое с глобальной переменной AlarmData, где вы выделили для нее память, но затем назначили адрес головы в AlarmData. В конце концов, это всегда адрес головы, с которым заканчивается AlarmData, а не копия головы, как вы планировали.

Необходимо скопировать содержимое головы в выделенную память AlarmData. То же самое с temp в начале кода.

Обратите внимание, что указатели содержат адреса, а не значения. Присвоение адреса указателя другому указателю не совпадает с копированием значений переменных, указываемых указателями.

+0

Я не думаю, что он должен копировать «содержимое головы в выделенную память AlarmData». AlarmData - это просто указатель на заголовок списка. Ему нужно только сделать копию параметра 'addNode'. Остальное поддерживает указатели связанных списков, включая указатель AlarmData, который является только указателем на голову. – NaotaSang

1

Есть несколько проблем с кодом.

temp = (node*)malloc(sizeof(node)); 
head = AlarmData;      
temp = addedNode; 

В вышеприведенном фрагменте кода вы выделить память для нового узла и точки temp на него. Две линии вниз, затем укажите temp на addedNode. Память, которую вы выделили в первой строке, теперь потеряна, поскольку вы перезаписали указатель на эту память. Вероятно, вы использовали *temp = *addedNode для копирования данных в addedNode в temp.

Вам не нужно выделять новый узел для AlarmData в конце функции. Вам просто нужно обновить указатель AlarmData, чтобы указать на новую голову (если глава действительно изменилась).

Смежные вопросы