为啥 const QString& 参数返回错误的 const char* 指向数据的指针

Posted

技术标签:

【中文标题】为啥 const QString& 参数返回错误的 const char* 指向数据的指针【英文标题】:Why const QString& param return bad const char* pointer to data为什么 const QString& 参数返回错误的 const char* 指向数据的指针 【发布时间】:2017-05-25 14:33:13 【问题描述】:

找出有趣的错误:当我传递const QString& 参数然后获得const char* 指向存储在const QString& 中的数据的指针时,指针指向错误数据(某些字符在我发送到函数时似乎没有)。

LogbookNote LBHasher::makePropsFromPseudoElement(const QString& id)

   LogbookNote rv;
   if (m_ctx->currentTrim) 
    const char* charId = id.toLatin1().data();
    ...
    qDebug() << charId;

以及调用代码:

LogbookNote LBHasher::makePropsByNameConvention(QString id)

   LogbookNote g;
   if (id.startsWith("_ctx_")) 
       g = makePropsFromPseudoElement(id);
 ...
 

正如您所提到的,调用方法 id 是 QString,即 QString 对象的完整副本。因此const QString&amp; 可以是一个强引用(例如,对已删除的临时对象没有破坏)。

为什么会出现这种行为?

【问题讨论】:

顺便说一句...qDebug() &lt;&lt; qPrintable( id ) 也许这个问题的标题需要更正? 【参考方案1】:

id.toLatin1() 创建一个临时的QByteArray 实例。然后,您存储指向由该临时管理的缓冲区的指针。在分号处,临时对象被销毁,指针悬空;稍后使用该指针会表现出未定义的行为。

【讨论】:

好的,重点。但为什么这种行为只发生一次?意思是当我第二次调用这个代码时,指针工作得很好。 “似乎有效”是未定义行为的一种可能表现形式。【参考方案2】:

QString::toLatin1 按值返回QByteArray,这意味着它是一个临时对象。 QByteArray 在该行的末尾被销毁(完整表达式),留下一个指向无效对象的指针,使用它是未定义的行为。

【讨论】:

以上是关于为啥 const QString& 参数返回错误的 const char* 指向数据的指针的主要内容,如果未能解决你的问题,请参考以下文章

为啥 lambda auto& 参数选择 const 重载?

QT & C++:传递 'const QString' 丢弃限定符

valueChanged(const Qstring &) 为空时不会在 qspinbox 中触发

为啥 const 模板参数不是通用/转发参考

为啥对按值传递的参数使用 const? [复制]

在Qt中如何将QString转换为const char*