首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在QString toUtf8()中崩溃

问在QString toUtf8()中崩溃
EN

Stack Overflow用户
提问于 2016-06-01 07:49:02
回答 1查看 1.7K关注 0票数 2

我有个插槽:

代码语言:javascript
复制
void Foo::func(QString str1, const QString& str2, int width, int height)
{
    std::unique_lock<std::mutex> _lock(m_mutex);

#ifdef _DEBUG
    MEMORYSTATUSEX statex;
    statex.dwLength = sizeof (statex);
    if (GlobalMemoryStatusEx(&statex)) {
        qDebug() << QString("There are %1 free MB of physical memory.\n").arg(statex.ullAvailPhys / 1024 / 1024);
    }
#endif

    BaseClass::someFunc(
        str1.toStdString(),
        str2.toUtf8().constData(),
        width,
        height
    );
}

这似乎是正确的,它是有效的。但是,如果程序工作很长时间(例如夜间),它就会在这个函数中崩溃。

代码语言:javascript
复制
str2.toUtf8().constData()

我最初认为这是一个基于线程的错误,但我的锁没有工作。所有局部变量和类成员都正常。崩溃错误是:

代码语言:javascript
复制
First-chance exception at 0x76E45B68 foo.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x00EFC6EC

但是从上面的代码中,MEMORYSTATUSEX显示可用内存是

代码语言:javascript
复制
There are 2314 free MB of physical memory

我也认为str2太大了,但是它的长度是49152,168441等等。有什么问题吗?我错过了什么吗?

堆栈跟踪:

代码语言:javascript
复制
    KernelBase.dll!_RaiseException@16()    Unknown
[External Code] 
Qt5Cored.dll!qBadAlloc() Line 2849  C++
Qt5Cored.dll!QByteArray::QByteArray(int size, Qt::Initialization __formal) Line 1409    C++
Qt5Cored.dll!QUtf8::convertFromUnicode(const QChar * uc, int len) Line 151  C++
Qt5Cored.dll!QString::toUtf8_helper(const QString & str) Line 4373  C++
Qt5Cored.dll!QString::toUtf8() Line 56  C++
foo.exe!Foo::func(QString str1, const QString & str2, int width, int height) Line 3600  C++
foo.exe!Foo::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 1126 C++
Qt5Cored.dll!QMetaObject::activate(QObject * sender, int signalOffset, int local_signal_index, void * * argv) Line 3717 C++
Qt5Cored.dll!QMetaObject::activate(QObject * sender, const QMetaObject * m, int local_signal_index, void * * argv) Line 3582    C++
foo.exe!SomeClass::func(QString _t1, const QString & _t2, int _t3, int _t4) Line 137    C++
foo.exe!SomeClass::qt_static_metacall(QObject * _o, QMetaObject::Call _c, int _id, void * * _a) Line 81 C++
Qt5Cored.dll!QMetaCallEvent::placeMetaCall(QObject * object) Line 485   C++
Qt5Cored.dll!QObject::event(QEvent * e) Line 1246   C++
Qt5Widgetsd.dll!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e) Line 3720    C++
Qt5Widgetsd.dll!QApplication::notify(QObject * receiver, QEvent * e) Line 3164  C++
Qt5Cored.dll!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event) Line 935  C++
Qt5Cored.dll!QCoreApplication::sendEvent(QObject * receiver, QEvent * event) Line 228   C++
Qt5Cored.dll!QCoreApplicationPrivate::sendPostedEvents(QObject * receiver, int event_type, QThreadData * data) Line 1552    C++
Qt5Cored.dll!QCoreApplication::sendPostedEvents(QObject * receiver, int event_type) Line 1410   C++
qwindowsd.dll!QWindowsGuiEventDispatcher::sendPostedEvents() Line 81    C++
Qt5Cored.dll!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned int wp, long lp) Line 414   C++
[External Code] 
Qt5Cored.dll!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 807    C++
qwindowsd.dll!QWindowsGuiEventDispatcher::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 73   C++
Qt5Cored.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 129   C++
Qt5Cored.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags) Line 204    C++
Qt5Cored.dll!QCoreApplication::exec() Line 1188 C++
Qt5Guid.dll!QGuiApplication::exec() Line 1508   C++
Qt5Widgetsd.dll!QApplication::exec() Line 2957  C++
foo.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * lpCmdLine, int __formal) Line 348    C++
[External Code] 

提前感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-02 21:33:39

对于那些像我这样的人,因为他们想把一个QString转换成一个char *,调用str.toUtf8().constData()或str.toUtf8().data(),但这导致程序崩溃,或者抛出一个像EXC_BAD_ACCESS on XCode那样的异常,这就是答案:

  • 在像foo = str.toUtf8().constData();这样的调用中,str.toUtf8()部件创建一个临时对象。
  • 对tmp.data()或tmp.constData()的调用返回指向由对象本身管理的内部缓冲区的指针,该缓冲区的生存期与临时对象的生存期相关联。来源。
  • 一旦执行该语句,其地址被分配给foo的对象(一旦由data()或constData()返回)的生存期将结束。
  • 因此,正如预期的那样,在该语句之后,foo将为其生命周期结束的对象保存一个地址,从而导致崩溃和异常。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37562530

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档