正如其他答案所说:分配n * m 条目以创建连续数据,然后可以将其包装在指针中以创建二维数组。
...绝对需要使用数组而不是向量...
我不确定vector 是否是基于正在使用的API 或要求的约束——但值得注意的是vector 可以 用于内存实现的管理 -- 同时仍然使用原始数据(可以通过&vec[0] 或vec.data() 访问,它返回指向数组第一个元素的指针,并且可以与接受原始数据的函数一起使用指针)。
由于这个问题是关于 c++ 的,一个选择是将n * m 的数组包装在class 中,作用 就像一个二维数组,但实际上是连续的。
一个简单的例子可以是:
class array_2d
{
public:
array_2d( std::size_t rows, std::size_t columns )
: m_rows(rows), m_cols(columns), m_array( new char[rows * columns] )
{
}
~array_2d()
{
delete [] m_array;
}
// row-major vs column-major is up to your implementation
T& operator()( std::ptrdiff_t row, std::ptrdiff_t col )
{
// optional: do bounds checking, throw std::out_of_range first
return m_array[row * m_cols + col];
// alternatively:
// return m_array[col * m_rows + row];
}
// get pointer to the array (for raw calls)
char* data()
{
return m_array;
}
private:
char* m_array;
std::size_t m_rows;
std::size_t m_cols;
};
(理想情况下,char* 应该是 std::unique_ptr<char[]> 或 std::vector<char> 以避免出现内存泄漏的情况,但既然你说 vector 不可行,我会尽量少写这个)
这个例子重载了调用运算符(operator())——但这也可以是像at(...)这样的命名函数;选择将取决于您。那么这种类型的使用将是:
auto array = array_2d(5,5); // create 5x5 array
auto& i01 = array(0,1); // access row 0, column 1
或者,如果[][] 语法对于表现得像一个二维数组很重要(而不是(r,c) 语法),您可以从调用重载的operator [](未经测试)返回代理类型:
class array_2d_proxy
{
public:
array_2d_proxy( char* p ) : m_entry(p){}
char& operator[]( std::ptrdiff_t col ){ return m_entry[col]; }
private:
char* m_entry;
};
class array_2d
{
...
array_2d_proxy operator[]( std::ptrdiff_t row )
{
return array_2d_proxy( m_array + (row * m_cols) );
}
...
};
这将允许您拥有“正常”的二维数组语法,同时仍然是连续的:
auto& i00 = array[0][0];