2016-06-22 2 views
0

В моей домашней работе меня попросили переместить определенный узел по его имени в определенный индекс. Мне трудно понять, почему мой список становится бесконечным списком. Проблема заключается в функции «changePlacement»
Пример:
Спрятать список: 1-> 2-> 3-> 4
Выход: 1-> 3-> 3-> 3 ...
Ожидаемый результат: 1-> 3-> 2-> 4Перемещение узла в односвязном списке создает бесконечную петлю

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

struct Frame 
{ 
    char   *name; 
    unsigned int duration; 
    char   *path; // may change to FILE* 
}; 
typedef struct Frame frame_t; 

struct Link 
{ 
    frame_t *frame; 
    struct Link *next; 
}; 
typedef struct Link link_t; 

int listLen = 0; 
link_t* lastNode = NULL; 

void addFrame(link_t** list); 
void frameData(frame_t* frame); 
void freeVideo(link_t* video); 
void showList(link_t* list); 
void freeNode(link_t* list); 
void changePlacement(link_t** list, int newIndex, char* name); 

int main(void) 
{ 
    link_t* video = NULL; 
    lastNode = video; 
    if (!video) 
    { 
     perror(video); 
    } 
    addFrame(&video); 
    addFrame(&video); 
    addFrame(&video); 
    addFrame(&video); 

    showList(video); 
    changePlacement(&video, 2, "3"); 
    showList(video); 
    printf("\n"); 
    freeVideo(&video); 

    _flushall(); 
    getchar(); 
    return 0; 
} 



void addFrame(link_t** video) 
{ 
    char strTemp[200] = { 0 }; 

    link_t* newFrame = (link_t*) calloc(1, sizeof(link_t)); 
    newFrame->frame = (frame_t*) malloc(sizeof(frame_t)); 

    printf("     *** Creating new frame ***\n"); 
    printf("Please insert a frame path:\n"); 
    scanf(" %s", &strTemp); 
    newFrame->frame->path = (char*) calloc(strnlen(strTemp, 200) + 1, sizeof(char)); 
    strncpy(newFrame->frame->path, strTemp, strnlen(strTemp, 200)); 

    printf("Please insert frame duration(in miliseconds):\n"); 
    scanf(" %d", &(newFrame->frame->duration)); 

    printf("Please choose a name for that frame:\n"); 
    scanf(" %s", &strTemp); 
    newFrame->frame->name = (char*) calloc(strnlen(strTemp, 200) + 1, sizeof(char)); 
    strncpy(newFrame->frame->name, strTemp, strnlen(strTemp, 200)); 

    if (!(*video)) 
    { 
     (*video) = newFrame; 
    } 
    else 
    { 
     lastNode->next = newFrame; 
    } 
    lastNode = newFrame; 


    ++listLen; 
} 




void freeVideo(link_t** video) 
{ 
    link_t* currNode = NULL; 
    int loop = 0; 

    for (; currNode; currNode = *video) // set curr to head, stop if list empty. 
    { 
     // advance head to next element. 
     freeNode(currNode); 
     (*video) = (*video)->next; // delete saved pointer. 
    } 
    freeNode((*video)->next); 
    freeNode((*video)); 


} 


void showList(link_t* list) 
{ 
    printf("\n\t|Name\t\t| Duration |  Path\n"); 
    printf("\t+++++++++++++++++++++++++++++++++++++++++++++++\n"); 
    for (;list; list = list->next) 
    { 
     printf("\t|%10s\t|%10d\t|\t%s\n", list->frame->name, list->frame->duration, list->frame->path); 
     printf("\t+++++++++++++++++++++++++++++++++++++++++++++++\n"); 
    } 
} 

void freeNode(link_t* node) 
{ 
    free(node->frame->name); 
    free(node->frame->path); 
    free(node->frame); 
    free(node); 
} 

void changePlacement(link_t** list, int newIndex, char* name) 
{ 
    link_t *prevOldNode = (*list), *prevTemp = NULL, *oldNode = NULL, *newNode = NULL; 
    link_t *temp = (*list), *PrevNewNode = NULL, *nodeAfterNewNode = NULL; 
    int currIndex = 0, i = 0, flag = 0; 

    while ((temp->next)) 
    { 
     ++currIndex; 
     if (!strcmp(temp->frame->name, name)) //looking for the wanted node 
     { 
      oldNode = temp; 
      prevOldNode = prevTemp; 
     } 
     if (currIndex == newIndex) 
     { 
      PrevNewNode = prevTemp; 
      newNode = temp; 
     } 
     prevTemp = temp; 
     temp = temp->next; 
    } 
    nodeAfterNewNode = newNode->next; //temporal variable that stores the node after the new node 
    prevOldNode->next = oldNode->next; 
    newNode->next = oldNode; 

    oldNode->next = nodeAfterNewNode; 
} 

У вас есть идеи после просмотра моего кода? любая помощь будет благословлена ​​

+0

Начало фиксируя ваши предупреждения. Затем отправьте код * в свой вопрос *. Ссылки могут умереть (и на самом деле, некоторые на самом деле рассчитывают на это), делая вопрос бесполезным для будущих читателей. – WhozCraig

+0

Спасибо, отредактировал :) – ilanDazanashvili

+0

Отлично, но [предупреждения (и на самом деле, ошибки) по-прежнему сохраняются] (http://pastebin.com/hzixMP7u). Вам нужно повысить уровни предупреждений до педантичных уровней на вашем компиляторе и адресовать * все * выявленные проблемы. Даже тогда есть некоторые вещи, которые компилятор будет * не * улавливать, например, ошибка в вашем 'freeVideo', которая из-за неправильной инициализации не освободит ничего, кроме первых двух узлов. Отладчик ** ** идеально подходит для решения этих проблем, включая бесконечный цикл, и, откровенно говоря, это следующий шаг после исправления ваших предупреждений/ошибок. – WhozCraig

ответ

0

Ваш код в конце changePlacement() не учитывает случай oldNode и newNode, прилегающих друг к другу, i. е. е. г. nodeAfterNewNode = newNode->next идентичен oldNode. (Кроме того, он не учитывает случай не нахождения имени.) Намного проще просто обменять указатели frame; изменить

nodeAfterNewNode = newNode->next; //temporal variable that stores the node after the new node 
    prevOldNode->next = oldNode->next; 
    newNode->next = oldNode; 

    oldNode->next = nodeAfterNewNode; 

к

if (!oldNode) return; // wanted node name not found 
    frame_t *f = oldNode->frame; 
    oldNode->frame = newNode->frame; 
    newNode->frame = f; 
Смежные вопросы