我有一个简单的类,其中包含这些也很简单的构造函数:
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/