【问题标题】:C pointer in append function is not updating value for head and tail附加函数中的 C 指针未更新头尾的值
【发布时间】:2019-07-18 04:01:12
【问题描述】:

创建了一个函数,该函数接受一个 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

【问题讨论】:

  • 显示list_initList的定义。你是存储一个双精度还是一个指针做一个双精度
  • @Inian 我想他可能正在存储指向void 的指针,因为他正在铸造。
  • 刚刚添加了list_init和List的定义

标签: c linked-list


【解决方案1】:

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

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

一旦appendTerm函数返回,this指针指向的变量已经超出范围,指针悬空,导致取消引用时出现Undefined Behavior。

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

解决方案是将双精度值存储在ListElmt 中,而不是指针。如果你必须存储一个指针,你需要malloc 存放它的空间(并在摆脱节点时释放该空间)。

【讨论】:

  • 感谢您的解释。当数据为 void* 类型时,如何将双精度值存储到函数中的 ListElmt。我不是 malloc 一个 ListElmt 所以它应该有空间来保存常量。抱歉,我对 C 编程有点陌生,所以有所有这些问题
  • 您可以通过将数据类型更改为double data 来存储双精度。如果您需要为其保留一个指针,则需要使用 element-&gt;data = malloc(sizeof(double)); *element-&gt;data = d;(但您需要在这两个语句之间添加错误检查以确保 malloc 成功)。
【解决方案2】:

下面两行需要交换。

pPolynomial->tail->next = element;
pPolynomial->tail = pPolynomial->tail->next;

因为pPolynomial-&gt;tail-&gt;next 在分配给尾部之前已被覆盖。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 2021-12-19
    • 1970-01-01
    • 2012-03-13
    • 2021-03-13
    • 1970-01-01
    • 2011-05-19
    相关资源
    最近更新 更多