好,所以我只做了幾個星期的C,並且遇到了一些問題。我有一個填充Bsig
指針的優先級隊列。作爲一個附加功能,我希望每當出現Bsig
時,我們都會執行自定義功能。爲什麼我不能從C中的返回結構調用函數指針?
typedef struct bsig{
// some more fields here, but they're not important
struct onpop_t *on_pop;
} Bsig;
typedef struct onpop_t {
struct onpop_t *next;
int (*do_on_pop)(Bsig *caller);
} Onpop;
int pop(SigPQ *q, Bsig* ret_sig){
if (q->size < 1){
return 0;
}
Bsig* signal = q->signals[0];
assert(signal);
q->signals[0] = q->signals[q->size-1];
q->size--;
sigpq_heapify(q,0);
if(signal->on_pop){
signal->on_pop->do_on_pop(signal);
}
ret_sig = signal;
return 1;
}
所以基本上,每當我們調用pop時,應該啓動do_on_pop函數。此外,pop會接收一個信號指針,該指針由隊列中彈出的任何內容覆蓋。所有這些都發生在main.c中包含的兩個文件中。以下是從主(其中testpop
是伸出打印出一些東西隨機的自定義功能 - 它宣佈在main.c文件中定義):
Bsig *sig1 = new_signal(1000, 0);
Onpop *onpop1 = malloc(sizeof(Onpop));
onpop1->do_on_pop = &testpop;
sig1->on_pop = onpop1;
push(pq, sig1);
Bsig *ret_sig;
pop(pq,ret_sig);
到目前爲止好 - 自定義功能testpop
被調用。但是
ret_sig->on_pop->do_on_pop(ret_sig);
from main給出了段錯誤!我不明白爲什麼。 ret_sig地址和信號地址應該是相同的,並且函數調用是相同的 - 唯一的區別是一個是從main調用的,另一個是從包含的.c文件中調用的。任何人都可以流光?
與調試C程序一樣,在調試器中運行程序並查看段錯誤發生的位置。還要檢查一些值;你是否在某處解除引用? –
「主要給出分段錯誤」根本沒有足夠的信息來回答你的問題。要麼指定哪一行代碼給出了分段錯誤,要麼 - 最好 - 執行一些調試,更深入地調查這個問題,並且 - 如果仍然需要的話 - 返回一個更準確的描述你遇到的問題。如果我沒有解決它, –
將返回更多信息。但是,我發現了ret_sig == NULL。謝謝,機器人評論:) :) –