C ++中的非连续数组指针

时间:2012-08-17 21:31:02

标签: c++ arrays pointers memory-management

我正在为C ++中的几个线性代数库编写包装代码,它可以将它们的数组存储为多种格式之一,最常见的是密集列主要,密集行主要,压缩稀疏列和压缩稀疏行。我想创建一个数组包装类,它将以通用顺序访问这些数组的元素,同时保持基本库所需的底层内存顺序;也就是说,我希望能够使用基于行的索引以相同的方式访问包装的列主要密集数组和包裹的行主要密集数组的元素。我不能在不干扰外部库的功能的情况下重新排序底层数组,并且考虑到我的阵列的巨大规模,重新排序将涉及大量的计算成本。这就是我的意思,假设'rowMajorArray'和'columnMajorArray'都在其外部库的适当顺序中存储类型'T'的值:

T * data;
// Initialize values of data

rowMajorArray R(data); // Stored row-major, with reordering of data if necessary
columnMajorArray C(data); // Stored column-major, with reordering of data if necessary

wrapperArray wrapperR(R); // DOES NOT reorder data
wrapperArray wrapperC(C); // DOES NOT reorder data

assert(wrapperR[3] == wrapperC[3]); // I want this to be true, i.e. transparent row indexing
assert(wrapperR[3][4] == wrapperC[3][4]); // I want this to be true, i.e. transparent element indexing


T * rowPointerR = wrapperR[0]; // Points to first row; should this be a reference: &(wrapperR[0]) ?
T * rowPointerC = wrapperC[0]; // Points to first row, even though stored column-major

assert( *(rowPointerR + 2) == *(rowPointerC + 2) ) // I want this to be true, i.e. transparent row pointers

T * elementPointerR = &(wrapperR[0][0]); // Points to individual element
T * elementPointerC = &(wrapperC[0][0]); // Points to individual element

assert( *(elementPointerR + 2) == *(elementPointerC + 2) ) // I want this to be true, i.e. transparent pointer arithmetic

基本上我的目标是让底层库能够使用与它们本机使用相同的内存顺序来访问包装数组,同时使我的包装器代码能够透明地访问数据而不必担心底层内存顺序。我不关心我是否使用指针或索引语法,因为我可以做任何我需要的任何事情,只要我可以正确访问行和元素;如果我只能直接实现指针,那么我将重载索引操作符,以便与其他外部运算符重载库轻松集成。

提前感谢大家的帮助。

2 个答案:

答案 0 :(得分:0)

您只需要重载索引操作符,并在所述操作符内部计算正确的偏移量。您的包装器需要知道它包装的数据结构类型。它可能就像在创建其中一种类型的实例时设置一些成员变量一样简单,即m_rowOffsetm_columnOffset等。

但是,你无法对指针的工作方式做任何事情。指针是简单,愚蠢的生物,你不能让它们以不同的方式工作以适应你的目的。如果将1添加到指针,它只是前进到下一个对象(即,提前n * sizeof(T)个字节)坚持使用索引方法。无论如何,它更自然。

答案 1 :(得分:0)

我当然不鼓励你使用多维数组和中缀运算符。

一个天真的起点就是这样一个简单的界面。

class Table {
public:
  virtual ~Table() {}

  virtual double get(size_t row, size_t col) const = 0;
  virtual void getRow(size_t row, std::vector<double> &row_vals) const = 0;
  virtual void getCol(size_t col, std::vector<double> &col_vals) const = 0;

  virtual void set(size_t row, size_t col, double val) = 0;
  virtual void setRow(size_t row, const std::vector<double> &row_vals) = 0;
  virtual void setCol(size_t col, const std::vector<double> &col_vals) = 0;
};

您将为每个存储策略实现接口。这将允许行/列主要优化他们擅长的地方。