在Qt应用程序中使用时出现奇怪的类行为

got*_*ch4 1 c++ qt

我有一个简单的类,这些也是简单的构造函数:

audio::audio() {
    channels = NULL;
    nChannels = 0;  
}

audio::audio(const char* filename) {
    audio();
    getFromFile(filename);
}
Run Code Online (Sandbox Code Playgroud)

(在此之前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;
...
Run Code Online (Sandbox Code Playgroud)

如您所见,它检查是否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();
        }
[...]
Run Code Online (Sandbox Code Playgroud)

它将具有channels != NULL(在调用第二个构造函数之后)并尝试删除未分配的指针(导致分段错误).使用GDB我发现它channels被设置为一些奇怪的值,而且nChannels......这闻起来像一个竞争条件,但显然似乎并非如此.我在插槽中检查是否aud != NULL要避免这种情况.你有什么想法?为什么会这样?我试图使用Valgrind并且它说channels != NULL我正在尝试使用未初始化的值进行条件跳转!怎么会这样?那些构造函数呢?

Nav*_*een 9

问题出在audio::audio(const char* filename) 构造函数中.第一个语句是audio();我认为你试图调用默认构造函数.但是,C++不允许一个ctor调用另一个ctor.所以你有未初始化的指针.如果你想做这样的事情,写一个init()调用的私有方法,并从两个构造函数中调用它.audio();语句使用默认ctor创建一个临时(未命名)音频对象,该语句在此语句后立即销毁.因此,您在此之后访问的对象是一个具有未初始化指针的不同对象.

  • 音频(); 创建一个对象,但由于你没有命名它,你以后无法访问它. (2认同)