注:后来发现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; } };