现在的位置: 首页 > 综合 > 正文

safty array

2013年12月06日 ⁄ 综合 ⁄ 共 2056字 ⁄ 字号 评论关闭

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

抱歉!评论已关闭.