內使用時我有一個簡單的類這些,也很簡單,構造函數:奇怪類行爲的Qt應用程序
audio::audio() {
channels = NULL;
nChannels = 0;
}
audio::audio(const char* filename) {
audio();
getFromFile(filename);
}
(這是audio():channels(NULL), nChannles(0), loaded(false){...
之前,我將在後面說爲什麼這個改變... )。功能getFromFile
開始是這樣的:
void audio::getFromFile(const char* filename) {
baseUtils::dynVec<float> *chans;
if (channels != NULL)
deleteChannels();
sox_format_t *in;
sox_sample_t buff[AUDIO_CLASS_READ_SAMPLES];
sox_sample_t sample;
...
正如你所看到的,它會檢查是否loaded
是真實的,如果它是運行在內部緩衝區一些delete
(S)。當然,從構造函數中可以看到,第一次運行loaded
爲false,那麼第二個構造函數會調用第一個構造函數,然後有loaded = false
。
如果我在一個簡單的命令行應用程序運行這個類,一切都正常運行。但如果我把它放在一個Qt應用程序,正是在做這個插槽:
void buttonPushed() {
QString s = QFileDialog::getOpenFileName();
std::cout << "file choosen: " << s.toStdString() << "\n";
sndfile = s.toStdString();
if (aud == NULL){
aud = new audio(sndfile.c_str());
ui.widget->setAudio(aud);
ui.widget->update();
}
[...]
將有channels != NULL
(調用第二構造之後),並嘗試刪除未分配的指針(導致分段故障)。使用GDB我發現channels
被設置爲一些奇怪的值,並且nChannels
太...這聞起來像一個競爭條件,但顯然似乎並不是這種情況。我在插槽中放了一張支票,看看是否爲aud != NULL
,以避免這種情況。你有什麼想法?爲什麼會發生?我試圖使用Valgrind,它說在channels != NULL
我試圖做一個有未初始化值的條件跳轉!怎麼會這樣?那麼構造函數呢?
audio();創建一個對象,但由於您沒有命名它,您以後無法訪問它。 – 2009-11-21 15:47:25
'audio()'創建一個新的臨時'音頻'對象,不會將它存儲在任何變量中(它會立即被再次銷燬)。 – sth 2009-11-21 15:49:27
你可以使用上面描述的init()方法,或者你可以對音頻進行子類化,爲它提供一個新的構造函數,並像下面這樣從新的構造函數中調用舊的:childClass():baseClass(){// ctor logic here } ....我想我更喜歡init()方法。 – 2009-11-21 15:51:07