std::array 的项目无意中脱离上下文而更改

Posted

技术标签:

【中文标题】std::array 的项目无意中脱离上下文而更改【英文标题】:Items of std::array are changed unintentionally out of context 【发布时间】:2021-05-31 11:18:12 【问题描述】:

我正在尝试通过构造函数将数组的引用传递给类对象,并操作该对象中的项目。 但是,恐怕数组中的这些项目在到达下面的 MySort::sort() 开头之后就会改变。 (在进入 MySort::sort() 之前没有改变)

#include <iostream>
#include <utility>
#include <array>

using namespace std;

template <typename T>
struct MySort

    T &_n;
    size_t _s;

public:
    MySort(T n) : _n(n)
    
        _s = _n.size();
    

    void sort()
    
        for (size_t i = 0; i < _s - 1; i++)
        
            for (size_t j = i + 1; j < _s; j++)
            
                if (_n[i] > _n[j])
                    std::swap(_n[i], _n[j]);
            
        
        cout << "teste" << endl;
    
    friend ostream &operator<<(ostream &ost, const MySort &c)
    
        for (size_t i = 0; i < c._s; i++)
            ost << c._n[i];
        return ost;
    
;

int main(int argc, const char **argv)

    array<int, 5> numbers2, 5, 1, 7, 3;

    MySort<array<int, 5>> bubblenumbers;
    bubble.sort();
    cout << bubble << endl;

    return 0;


在通过副本传递数组的情况下,它可以正常工作。

感谢您的关注。

【问题讨论】:

【参考方案1】:

构造函数

MySort(T n) : _n(n)

    _s = _n.size();

在这里,您设置_n 引用一个输入对象,该对象将在离开构造函数时被销毁。这是普通的 UB。

修复它写

MySort(T& n) : _n(n)

    _s = _n.size();

【讨论】:

我明白了。非常感谢。要修复的示例对我很有帮助!【参考方案2】:

在构造函数MySort(T n) 中,您正在制作数组的副本,然后存储对该副本的引用,但随后副本超出范围,因此您有一个悬空引用。

如果要使用引用,则应传递对原始对象MySort(T &amp;n) 的引用,并确保原始对象在 MySort 对象的生命周期内始终位于范围内。

【讨论】:

非常感谢您的快速回答!

以上是关于std::array 的项目无意中脱离上下文而更改的主要内容,如果未能解决你的问题,请参考以下文章

为啥 std::array::size constexpr 具有简单类型(int,double,...)而不是 std::vector (GCC)?

为啥我可以从 初始化常规数组,而不是 std::array

为什么c ++用零来初始化std :: vector,而不是std :: array?

通过在堆栈上传递std :: array进行API调用是否有优势

如何静态断言 std::array 成员的大小

std::array 的嵌套聚合初始化