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

标签 c++ 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 是否为 true,以及是否在内部缓冲区上运行一些 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::audio(const char* filename) 构造函数中。第一条语句是 audio(); 我相信您正在尝试调用默认构造函数。但是,C++ 不允许一个构造函数调用另一个构造函数。所以你有未初始化的指针。如果您想做这样的事情,请编写一个名为 init() 的私有(private)方法,并从两个构造函数中调用它。 audio(); 语句使用默认构造函数创建一个临时(未命名)音频对象,该构造函数在此语句后立即销毁。因此,您在此之后访问的对象是一个具有未初始化指针的不同对象。

关于c++ - 在 Qt 应用程序中使用时出现奇怪的类行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1775784/

相关文章:

c++ - xcode 中的子文件夹。链接

c++ - OpenCV 3.0.0 "configure"失败,未下载 ffmpeg

macos - 使用 QSystemTrayIcon 为 OS X 创建单色托盘图标

Qt设计器: Setting fixed size of QLabel

c++ - 从源代码编译 Qt 5.3 失败

c++ - Qt 旋转图像 -> 多边形

C++:通用函数包装类作为非模板类​​的成员

c++ - 对 C++ 中的通用对象的 undefined reference

c++ - C++调用回调后删除一个对象

qt - 仅设置 MainWindow Qt 的背景颜色