![](/img/trans.png)
[英]In an array of pointers in C++ does memory overcommitting result in the pointers to be stored in non-contiguous blocks of memory?
[英]Non-contiguous array pointers in C++
我正在为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
本质上,我的目标是使基础库能够使用与本机使用的相同的内存顺序访问包装的数组,同时使我的包装程序代码透明地访问数据而不必担心基础内存的顺序。 我不在乎是否使用指针语法或索引语法,因为只要可以正确访问行和元素,就可以使用任何一种方法进行处理。 如果我只能直接实现指针,则无论如何我都将重载索引运算符,以允许与其他外部运算符重载的库轻松集成。
在此先感谢大家的帮助。
您只需要重载索引运算符,并在该运算符内部计算正确的偏移量即可。 包装器将需要知道它包装的是哪种数据结构。 创建这些类型之一的实例(即m_rowOffset
, m_columnOffset
等)时,设置几个成员变量可能很简单。
但是,您不能对指针的工作方式做任何事情。 指针是简单而又愚蠢的生物,您不能使其适应自己的目的而有所不同。 如果将1
加到指针,它只是前进到下一个对象(即,前进n * sizeof(T)
个字节)。继续使用索引方法。 反正更自然。
我当然不鼓励您使用多维数组和中缀运算符。
天真的出发点就是这样的简单界面。
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;
};
您将为每种存储策略实现接口。 这将使行/列专业可以优化其优势。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.