safty array
3565 ワード
注:後でboostのMulti_を発見arrayは使いやすく、自分で格納方法が行か列か、baseが0か1かを指定することもできます.最も重要なのは、1次元配列と同じポインタで問題を解決できることです.
前回1つの配列の境界を越える問題に出会って調べるのが難しくて、いつもcrashが異なる位置にいて、ちょうど最近fortranからC/C++までの翻訳の仕事をしていて、中にも多くの配列の動作があって、その上配列は多くのパラメータを伝達して、例えば2次元の配列は更に1つのNとMが2つの次元の長さを表すことを伝達して、ちょうど前に本「Optimizing software in C++」を読んだことがありますが、作者は良いパッケージを実現しました.
C動的多次元配列の操作は面倒であり,特に初期化と削除の際には1次元の配列として扱うことが望ましい(以下のコードを参照).
前回1つの配列の境界を越える問題に出会って調べるのが難しくて、いつもcrashが異なる位置にいて、ちょうど最近fortranからC/C++までの翻訳の仕事をしていて、中にも多くの配列の動作があって、その上配列は多くのパラメータを伝達して、例えば2次元の配列は更に1つのNとMが2つの次元の長さを表すことを伝達して、ちょうど前に本「Optimizing software in C++」を読んだことがありますが、作者は良いパッケージを実現しました.
C動的多次元配列の操作は面倒であり,特に初期化と削除の際には1次元の配列として扱うことが望ましい(以下のコードを参照).
#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;
}
};