c++ - 段错误仅在发布配置下发生

标签 c++ qt

由于某些奇怪的原因,当我切换到发布版并在调试器之外运行时,我的应用程序喜欢中断。这是对我有用的,这是对我不起作用的

(Qt Creator 是 IDE)

  • 使用调试配置进行调试 - ok
  • 使用调试配置运行 - ok
  • 使用发布配置进行调试 - ok
  • 使用发布配置运行 - 应用程序崩溃

我的 UI 是一个项目,一些东西的核心是一个单独的依赖项。在 Windows 上(使用 MSVCC 编译),我点击了一个菜单按钮,它最终调用了一个函数。在该函数中,应用程序在向 vector 添加新元素时中断。例如:

str *x = new str();
str *y = new str();
/* ...set some of x & y's members... */
vector.push_back(x); // works fine
vector.push_back(y); // causes crash

如果我注释掉 vector.push_back(y); 这行,应用程序继续没有问题,直到应用程序离开事件范围(即 OnMenuButtonClick 的结尾)。在 OS X 上,它类似于向 vector 添加元素的问题,除了我有:

std::vector<foo *> SomeFunction()
{
   std::vector<foo *> returningVector;
   /* do stuff */
   std::vector<foo *> goo = GetFooObjects();
   for (int i = 0; i < goo.size(); i++)
   {
       returningVector.push_back(goo[i]); // breaks here
   }
}

那么在没有附加调试器且不在调试配置下这种奇怪行为的一些原因是什么?我已经检查以确保我的所有变量都已初始化,所以我很困惑。如果要查看上面的代码,第一部分可以位于here , 第二部分 here .请原谅您认为“不好”的任何内容,如果您有无法包含的建议,请在 GitHub 上给我发消息。

编辑:

我仔细研究了它,并找出了导致问题的确切原因,但不知道如何解决。这是我的应用程序崩溃的功能(在 OS X 上):

vector<Drive *> Drive::GetFATXDrives( bool HardDisks )
{
    vector<Drive *> Return;
    if (HardDisks)
    {
        vector<DISK_DRIVE_INFORMATION> Disks = GetPhysicalDisks();
        for (int i = 0; i < (int)Disks.size(); i++)
        {
            DISK_DRIVE_INFORMATION ddi = Disks.at(i);
            // First, try reading the disk way
            Streams::xDeviceStream* DS = NULL;
            try
            {
                char path[0x200] = {0};
                wcstombs(path, ddi.Path, wcslen(ddi.Path));
                DS = new Streams::xDeviceStream(ddi.Path);
            }
            catch (xException& e)
            {
                continue;
            }

            if (DS == NULL || DS->Length() == 0 || DS->Length() < HddOffsets::Data)
            {
                // Disk is not of valid length
                continue;
            }
            DS->SetPosition(HddOffsets::Data);

            // Read the FATX partition magic
            int Magic = DS->ReadInt32();
            // Close the stream
            DS->Close();

            // Compare the magic we read to the *actual* FATX magic
            if (Magic == FatxMagic)
            {
                Drive *d = new Drive(Disks.at(i).Path, Disks.at(i).FriendlyName, false);
                Return.push_back(d);
            }
        }
    }

    vector<Drive *> LogicalDisks = GetLogicalPartitions();
    for (int i = 0; i < (int)LogicalDisks.size(); i++)
    {
        Return.push_back(LogicalDisks.at(i));
    }

    return Return;
}

如果我改变 if (HardDisks)if (HardDisks = false) ,该应用程序运行良好。所以,我查看了那个范围,发现在 vector<DISK_DRIVE_INFORMATION> Disks = GetPhysicalDisks(); 之后,堆会损坏或类似的东西。我注意到这一点是因为在调试器中,调用该函数后,我的 HardDisks bool 变为“false”,这与之前不同。

这里是 GetPhysicalDisks :

vector<Drive::DISK_DRIVE_INFORMATION> Drive::GetPhysicalDisks( void )
{
    // RIGHT AFTER this vector is initialized, everything goes to hell
    vector<Drive::DISK_DRIVE_INFORMATION> ReturnVector;

DIR *dir;
dirent *ent;
dir = opendir("/dev/");
if (dir != NULL)
{
    // Read the shit
    while ((ent = readdir(dir)) != NULL)
    {
        // Check the directory name, and if it starts with "disk" then keep it!
        QRegExp exp("disk*");
        exp.setPatternSyntax(QRegExp::Wildcard);
        exp.setCaseSensitivity(Qt::CaseInsensitive);
        if (exp.exactMatch(ent->d_name))
        {
            DISK_DRIVE_INFORMATION curdir;
            memset(curdir.FriendlyName, 0, sizeof(curdir.FriendlyName));
            memset(curdir.Path, 0, sizeof(curdir.Path));

            char diskPath[0x50] = {0};
            sprintf(diskPath, "/dev/r%s", ent->d_name);

            mbstowcs(curdir.Path, diskPath, strlen(diskPath));

            int device;
            if ((device = open(diskPath, O_RDONLY)) > 0)
            {
#ifdef __linux
                hd_driveid hd;
                if (!ioctl(device, HDIO_GET_IDENTITY, &hd))
                {
                    swprintf(curdir.FriendlyName, strlen(hd) * 2, L"%hs", hd.model);
                }
#elif defined __APPLE__
                mbstowcs(curdir.FriendlyName, ent->d_name, strlen(ent->d_name));
#endif
                ReturnVector.push_back(curdir);
            }
        }
    }
}
    return ReturnVector;
}

最佳答案

虽然这不是关于发生了什么的真正答案,但我确实找到了解决问题的方法。查看上面的编辑,我编辑了我的 Drive::GetFATXDrives像这样的功能:

vector<Drive *> Drive::GetFATXDrives( bool HardDisks )
{
    // Initialize Disks vector up here
    vector<DISK_DRIVE_INFORMATION> Disks;
    // Call the function to get the hard disks
    if (HardDisks)
        Drive::GetPhysicalDisks(Disks);

    vector<Drive *> ReturnVector;
    if (HardDisks)
    {
        Streams::xDeviceStream* DS = NULL;
        for (int i = 0; i < (int)Disks.size(); i++)
        {
            /* ... */
        }
        if (DS)
        {
            DS->Close();
            delete DS;
        }
    }

    vector<Drive *> LogicalDisks = GetLogicalPartitions();
    for (int i = 0; i < LogicalDisks.size(); i++)
    {
        ReturnVector.push_back(LogicalDisks[i]);
    }

    return ReturnVector;
}

还有我的Drive::GetPhysicalDisks函数现在需要 vector<DISK_DRIVE_INFORMATION>引用而不是返回一个。在那之后似乎让我的程序工作得很好。

关于c++ - 段错误仅在发布配置下发生,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9858304/

相关文章:

c++ - Qt Parent 在 child 关闭后删除变量

c++ - 未能优化看似明显的循环不变量(但 volatile 限定符确实有魔力)

c++ - 查看缓存缺失 - 简单的 C++ 缓存基准测试

c++ - 如何在 Qt 中更改窗口的标题?

c++ - 针对特定版本的 armhf g++ 进行编译

C++/JNI 大括号括起来的初始化程序映射 (Android NDK)

c++ - 通过标准算法。模板推导

qt - 如何使用 QPainter 类围绕圆圈编写文本?

c++ - 如何在 C++ 中获取操作系统名称?

c++ - 将 Jenkins CI 用于 Qt 项目