首页 > 解决方案 > 附加函数中的 C 指针未更新头尾的值

问题描述

创建了一个函数,该函数接受一个 List Struct 指针和一个 double 值,该值是要存储在链表中的数据。当我调用函数来添加值时,它们被存储为头部和尾部,并且以前的值没有被保存。

列表结构:

typedef struct LIST_{
    int size;

    int (*match)(const void *key1, const void *key2);
    void (*destroy)(void *data);

    ListElmt *head;
    ListElmt *tail;
}List;

list_init 函数:

void list_init(List *pPolynomial, void (*destroy)(void *data)){
    pPolynomial->size = 0;
    pPolynomial->destroy = destroy;
    pPolynomial->head = NULL;
    pPolynomial->tail = NULL;

}

附加项功能:

List* appendTerm(List *pPolynomial, double constant){
//inserting value at the end of the list
    ListElmt *element;
    element = (ListElmt *)malloc(sizeof(ListElmt));
    double* d = &constant;
    element->data = d;

    if(pPolynomial->size == 0){
        //if there was no head
        pPolynomial->head = element;
        pPolynomial->tail = element;
        element->next = NULL;
        printf("This is the data stored in the head %f \n", *(double*)pPolynomial->head->data);
        printf("This is the data stored in the tail %f \n", *(double*)pPolynomial->tail->data);
    }
    else{
        //there is a head
        pPolynomial->tail = pPolynomial->tail->next;
        pPolynomial->tail->next = element;

        element->next = NULL;
        printf("else statement: This is the data still stored in the head %f \n", *(double*)pPolynomial->head->data);
        printf("This is the data stored in the tail %f \n", *(double*)pPolynomial->tail->data);
    }
    pPolynomial->size++;
    printf("size: %d\n", pPolynomial->size);

    return pPolynomial;
}



int main() {
    List* listOfInts;
    ListElmt *pElmt;
    double *pDbl;
    int i;


    list_init(listOfInts, free);
    listOfInts = appendTerm(listOfInts, 5);
    listOfInts = appendTerm(listOfInts,6);
    listOfInts = appendTerm(listOfInts,7);

    pElmt = listOfInts->head;
    for (int i = 0; i < 3; i++)
    {
        double d = *(double *) pElmt->data;
        printf("List elem %d = %f\n", i, d);
        pElmt = pElmt->next;
     }


    return (EXIT_SUCCESS);
}

这是程序的输出:

This is the data stored in the head 5.000000 
This is the data stored in the tail 5.000000 
size: 1
else statement: This is the data still stored in the head 6.000000 
This is the data stored in the tail 6.000000 
size: 2
else statement: This is the data still stored in the head 7.000000 
This is the data stored in the tail 7.000000 
size: 3
List elem 0 = 7.000000
List elem 1 = 0.000000
List elem 2 = 0.000000

标签: clinked-list

解决方案


无需在列表中存储指向 double 的指针。只需存储双倍。存储指针的问题是管理它。在您的情况下,您在结构中存储一个指向局部变量的指针:

double* d = &constant;
element->data = d;

一旦appendTerm函数返回,this 指针指向的变量已经超出范围,并且指针悬空,导致取消引用时出现未定义行为。

这个(在您的测试中)的最终结果是所有节点都指向相同的内存位置,该位置(在您打印列表内容时)仍然保存存储在列表中的最后一个值。

解决方案是将 double 存储在其中ListElmt而不是指针。如果您必须存储一个指针,您将需要malloc空间来保存它(并在摆脱节点时释放该空间)。


推荐阅读