c - заменить функцию связанного списка - PullRequest
0 голосов
/ 07 февраля 2011

Может кто-нибудь сказать мне, почему функция замены не работает? скажем main называется replace (1,2, список). Он должен искать узлы, и если значение узла равно 1, он должен создать новый узел со значением 2 для его замены, а затем освободить память, выделенную первому узлу. Я не могу понять это = (

typedef struct iNode
{
    int myInt;
    struct iNode* next;
} IntNode, *IntNodePtr;

IntNodePtr insert(int i, IntNodePtr p)
{
    IntNodePtr newp = malloc(sizeof(struct iNode));
    newp->myInt = i;
    newp->next = p;
    return newp;
}

IntNodePtr delete(int i, IntNodePtr p)
{
    /* End of list check */
    if(p == NULL)
        return NULL;

    /* Check if current node is the one to delete */
    if(p->myInt == i)
    {
        IntNodePtr temp;
        temp = p->next;

        free(p);
        return temp;
    }

    p->next = delete(i, p->next);
    return p;
}

IntNodePtr replace(int i, int j, IntNodePtr p)
{
    if(p == NULL)
        return NULL;

    if(p->myInt == i)
        insert(j, p->next);

    free(p);

    p->next = replace(i, j, p->next);
    return p;
}

Ответы [ 2 ]

0 голосов
/ 07 февраля 2011

Как отметил Марк, ваше free(p) имеет неопределенное поведение.Следовательно, следующий оператор

p->next = replace(i, j, p->next);

становится недопустимым, поскольку вы пытаетесь присвоить p->next значению указателя, но p->next сама область памяти не определена.

Но почему вы сделали эту функцию рекурсивной?Будет достаточно простого цикла while.

IntNodePtr replace(int i, int j, IntNodePtr p) {
    if(p == NULL)
        return NULL;
    IntNodePtr prevPtr = NULL;
    while(p){
        if(p->myInt == i){
            IntNodePtr temp = insert(j, p->next);
            if(prevPtr)
                 prevPtr->next = temp;
            free(p);
            break;
        }
        prevPtr = p;
        p = p->next;
    }
}

И вы также неправильно используете свою функцию вставки, поскольку вы не подключаете предыдущий узел к вновь созданному узлу.

0 голосов
/ 07 февраля 2011

Есть несколько проблем с вашей функцией replace(). (Это выглядело хорошо для меня в вашем последнем вопросе).

  1. Вы вызываете insert(), когда находите узел с i, но ничего не делаете с новым узлом (что возвращает insert()). По сути, новый узел, который вы вставляете, это новый p, поэтому вы должны установить p.

  2. Вы освобождаете p и сразу пытаетесь установить для поля next значения p значение. Местоположение, на которое указывал p, недопустимо, поэтому вам не следует этого делать. Вы должны использовать временную переменную для сохранения старого p, чтобы вы могли освободить его позже. Это следует делать только в том случае, если вы фактически замените его, поэтому оно должно быть частью предыдущего условия.

Я думаю, что это должно покрыть это. В основном изменения:

/* if the current node contains the int I'm looking for... */
if(p->myInt == i)
{   /* ... the current node needs to be replaced */
    /* save the current node to delete later (2) */
    IntNodePtr oldNode = p;

    /* insert a new node making it the new current node (1) */
    p = insert(j, oldNode->next);

    /* free the old node (2) */
    free(oldNode);
}
/* and so on */
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...