首页 > 解决方案 > C/Cython 返回值部分取决于返回值的帧/函数

问题描述

几天来,我一直在尝试调试这个 C/Cython 程序,而且我已经非常接近了。我正在使用的priorityqueue 库pqueue_insert提供和pqueue_pop. 我的 Cython 伪代码如下所示:

pick_pop_location = ? // set to 1 or 2
cdef void main():
    node_t current_element, pqueue_t* pq = initialize() // exact implementation doesn't matter
    push_wrapper(pq, &current_element)
    if pick_pop_location == 1:
        popped_after_returning_to_main = (<node_t*>pqueue_pop(pq))[0]
        print(popped_after_returning_to_main)

cdef void push_wrapper(pqueue_t* pq, node_t* current_element):
    node_t new_element = build_new_element(current_element) // exact implementation doesn't matter
    pqueue_insert(pq, &new_element)
    if pick_pop_location == 2:
        popped_immediately = (<node_t*>pqueue_pop(pq))[0]
        print(popped_immediately_inside_push_wrapper)

node_t看起来像这样:

ctypedef struct node_t:
    pqueue_pri_t m
    int row
    int col

(请注意,我改为pqueue_pri_t代替doublein unsigned long long' libpqueues pqueue.h,虽然这无关紧要,但我只是在这里做尽职调查)。

现在是有趣的部分。如果我设置pick_pop_location = 2它将打印

// popped_immediately_inside_push_wrapper

{'m':-1456.645295,'row':244,'col':1}

...这是正确的。但如果我设置pick_pop_location = 1它会打印

// popped_after_returning_to_main

{'m':-1456.645295,'row':-1739027664,'col':32764}

...这是部分不正确的:'m' 值是保留的,但 'row' 和 'col' 值随机变化(每次运行程序时它们都会变化)。

这怎么可能发生?push_wrapper退出框架后(显然)出了什么问题?

我该如何调试呢?我没有在帧之间更改值的经验。

标签: cfunctiondebuggingcython

解决方案


给出一个不完整的例子,这里有很多猜测:

node_t new_element = build_new_element(current_element)

new_element在堆栈上分配 - 它仅在push_wrapper运行时存在。

pqueue_insert(pq, &new_element)

我猜这会存储指针,而不是元素的新副本。返回后push_wrapper指针指向胡说八道。


就你如何调试而言:这种行为是非常典型的悬空指针:要么你试图从一个不再有效的指针中读取(就像我认为在这里发生的那样),要么你已经写入一个不再有效的指针有效的。堆栈分配的变量是不再有效指针的明显来源。


推荐阅读