std::vector<QString,int*> 的奇怪行为

Posted

技术标签:

【中文标题】std::vector<QString,int*> 的奇怪行为【英文标题】:Strange behaviour of std::vector<QString,int*>std::vector<QString,int*> 的奇怪行为 【发布时间】:2018-07-08 09:19:31 【问题描述】:

考虑以下程序:

#include <QString>
#include <QDebug>
#include <vector>

class A 
public:
    QString str;
    int *pointer;
    A(QString s) : str(s), pointer(0) 
;

int main() 
    std::vector<A> v;
    v.emplace_back("111");
    v.emplace_back("222");
    v.emplace_back("333");
    v.emplace_back("444");
    v.emplace_back("555");
    for (const A &a : v)
        qDebug() << a.str;
    return 0;

当使用g++ main.cpp -O3 -std=c++17 -Wall -fPIC -I/usr/include/qt -I/usr/include/qt/QtCore -lQt5Core(GCC 版本 8.1.1、Qt 版本 5.11.1、Arch Linux)编译时,会产生以下意外输出:

""
""
""
""
"555"

但是,当使用 -O2 或 clang++ 或显式请求默认复制构造函数时,它可以工作:

A(const A &b) = default;

代码有什么问题? (当增加向量的大小时,移动操作中可能会发生一些不好的事情?)

【问题讨论】:

我没有发现任何问题。 QString类是如何定义的,尤其是赋值运算符和拷贝构造函数? 文档是here 和here。对我来说似乎很简单。 (与 std::string 最明显的区别是 QString 实现了写时复制,因此“复制”是一个恒定时间操作。但我不明白这会是什么问题。)你可以找到源代码分配代码here. 为我打印所有这些(Qt 5.9.5,GCC 7.3)。 这里(GCC 8.1.0;Qt 5.10.1,在 Debian 上),它适用于 -O3 -march=native,但单独使用 -O3 时失败。 您的假设的其他证据 - 在任何构造之前调用 v.reserve(10) 将使其工作。此外,添加显式移动构造函数 A(A&amp;&amp; b) : str(std::move(b.str)), pointer(std::move(b.pointer)) 不会改变任何东西 - 但将 str(std::move(b.str)) 更改为 str(b.str) 确实可以工作。 【参考方案1】:

原来这是 GCC 中的一个错误:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87665

感谢您的帮助!

【讨论】:

以上是关于std::vector<QString,int*> 的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

如何在 QT 中正确显示 std::vector?

为啥 std::array<std::pair<int,int>, 3> 不能使用嵌套初始化列表初始化,但 std::vector<std::pair<int,in

继承 std::vector 时出错

当C ++将元素从函数的返回值存储到std :: vector时出现意外的结果

发送具有 std::vector 成员的结构时出现分段错误

openCV:将垫子保存到矢量<vector<int>>