为什么读取int*const&会导致分段错误?

问题描述 投票:0回答:1

为什么以下对

int*const&
的读取访问会导致分段错误?

#include <iostream>

class X{
    int A[3][4] = {0};
public:
    int*const&p=*A;
    void print()const{
        for(int i=0;i<3;++i){
            for(int j=0;j<4;++j){
                std::cout << A[i][j] << " , ";
            }
            std::cout << "\n";
        }
    }
};

int main() {
    X x;
    x.p[2] = 3;
    x.print(); // until this point, everything works as intended

    std::cout << x.p[2] << "\n"; // why does read-access of p trigger segmentation fault?
}

输出

0 , 0 , 3 , 0 , 
0 , 0 , 0 , 0 , 
0 , 0 , 0 , 0 , 
Segmentation fault

应用上下文

我想要一个 n 维数组

A
用于内部计算,并且在动态编程上下文中更容易索引,但外部接口请求一个指向 1D 数组的指针
p

潜在的解释

int*const& p=*A;
替换为
int*const p=*A;
时,上述代码有效。真正的问题是 A[][] 的内部 int 数组无法进行赋值吗?

c++ pointers reference segmentation-fault
1个回答
0
投票

在当前的 C++ 中,您将使用 std::array 和对该数组的引用(就像任何其他 C++ 对象一样,您可以从函数返回 std::array )。 你不应该拥有公共数据,总是提供 getter(使用 auto 关键字当然更容易重构)。

#include <array>
#include <iostream>

class X
{
public:

    //read only (used when there is a "const X" or "const X&" being used
    //like in stream operator below
    // No need type std::array<std::array<int, 4>, 3> over and over again, just use auto
    const auto& get_values() const noexcept
    {
        return m_values;
    }

    // read/write for non-const situations.
    auto& get_values() noexcept
    {
        return m_values;
    }

private:
    // nice thing about std::array is you can return
    // it from functions by (const) reference (like get_values)
    std::array<std::array<int, 4>, 3> m_values{};
};


// replacement of your print, generic output to a stream
std::ostream& operator<<(std::ostream& os, const X& x)
{
    auto& values = x.get_values();

    // whenever you can use range based for loops
    for (const auto& row : values)
    {
        bool comma{ false };
        for (const auto& value : row)
        {
            if (comma) os << ", ";
            os << value;
            comma = true;
        }
        os << "\n";
    }

    return os;
}
    

int main() 
{
    X x;

    // get a reference to the 2D array
    auto& values = x.get_values();

    // then assign a value into this array
    // this is also where one of your mistakes was, assinging an int to a whole row
    values[2][2] = 3;
 
    std::cout << x; // use stream operator for X

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.