注:后来发现boost的Multi_array很好用,甚至可以自己指定存储的方式是按照行还是列,以及指定base从0还是1,最重要的一点就是可以和一维数组一样一个指针解决问题。
上次遇到一个数组越界的问题很难查,总是会crash在不同的位置,刚好最近在做一个从fortran到C/C++的翻译工作,里面也有很多数组的动作,而且数组要传递很多参数,比如二维的数组就要再传递一个N和M表示两个维度的长度,刚好之前看过一个书《Optimizing software in C++》里面作者实现了一个很好的封装。
C对动态的多维的数组的操作很麻烦,尤其是初始化和删除的时候, 所以最好当作一维的数组来处理(见下面的代码)。
#include <memory.h> // For memcpy and memset
#include <stdio.h> // Needed for example only
#include <malloc.h>
// Template for safe array with bounds checking
template <typename T, unsigned int N> class SafeArray {
T a[N]; // Array with N elements of type T
public:
// Constructor
SafeArray() {
memset(a, 0, sizeof(a)); // Initialize array to zero
}
// Return the size of the array
int Size() const {
return N;
}
// Safe [] array index operator
T & operator[] (unsigned int i) {
if (i >= N) {
// Index out of range. The next line provokes an error.
// You may insert any other error reporting here:
return *(T*)0; // Return a null reference to provoke error
}
// No error
return a[i]; // Return reference to a[i]
}
};
template <typename T> class SafeDynamicArray {
T* a;
unsigned int N; // Array with N elements of type T
public:
// Constructor
SafeDynamicArray(unsigned int size) : N(size){
a=(T*)calloc(N, sizeof(T));
}
~SafeDynamicArray(){ if(a) delete[] a; }
SafeDynamicArray& operator=(const SafeDynamicArray<T>& rhs){
if(&rhs == this) return *this;
delete[] a;
a = calloc(rhs.Size(), sizeof(T));
memcpy(a, rhs[0],sizeof(T)*rhs.Size());
return *this;
}
// Return the size of the array
int Size() const {
return N;
}
// Safe [] array index operator
T & operator[] (unsigned int i) {
if (i >= N) {
// Index out of range. The next line provokes an error.
// You may insert any other error reporting here:
return *(T*)0; // Return a null reference to provoke error
}
// No error
return a[i]; // Return reference to a[i]
}
};
template <typename T> class Array2D{
SafeDynamicArray<T>* _data;
int _row;
int _col;
public:
Array2D(int row, int col):_row(row), _col(col){
_data= new SafeDynamicArray<T>(_row*_col);
}
~Array2D(){if(_data) delete _data; }
T& at(int i, int j){ // base 0,0
int index=i*_col+j;
return (*_data)[index];
}
int row()const{return _row; }
int col()const{return _col; }
Array2D& operator=(const Array2D<T>& rhs){
if(&rhs == this) return *this;
delete[] _data;
_data= new SafeDynamicArray<T>(rhs.row()*rhs.col());
_data->operator=(*(rhs._data));
return *this;
}
};