为指针向量赋值
Posted
技术标签:
【中文标题】为指针向量赋值【英文标题】:Assigning values to a vector of pointers 【发布时间】:2018-11-08 13:27:09 【问题描述】:我正在将一些算法翻译成 C++(我用 R 编写并且已经用原始指针翻译成 C++)。原始 C++ 翻译的问题在于它会因大型矩阵而崩溃并遭受内存泄漏(但比 R 快大约 1000 倍,这太棒了)......所以我再次尝试使用向量。基本上我有一个零和一的矩阵,并想用一个表示组的数字替换这些矩阵。 一个组将由水平或垂直连接的单项定义。 为此,我建立了一个指针矩阵并在此过程中更改它们指向的组索引。
下面的代码是摘录的。
vector<int> groups(vector<int> matrix, int nrow, int ncol)
vector<connection> connections;
vector<int *> pointersToIndices;
int zeroGroupIndex = 0;
int* O = &zeroGroupIndex;
int currentN = 1;
int size = nrow * ncol;
vector<int **> pointerMatrix;
for (int i = 0; i < size; i++)
int** OO = &O;
pointerMatrix.push_back(OO);
int col, row, index, leftIndex, upperleftIndex, upperIndex;
for (col = 0; col < ncol; col++)
for (row = 0; row < nrow; row++)
index = nrow * col + row;
if (matrix[index] != 0)
upperIndex = nrow * col + row - 1;
leftIndex = nrow * (col - 1) + row;
if (row == 0 || matrix[upperIndex] == 0)
currentN++;
matrix[index] = currentN;
pointersToIndices.push_back(&(matrix[index]));
// I assume the following does not do what i intend
pointerMatrix[index] = &pointersToIndices.back();
else pointerMatrix[index] = pointerMatrix[upperIndex];
if (col != 0 && matrix[leftIndex] != 0) *pointerMatrix[index] = *pointerMatrix[leftIndex];
....
....
现在的问题是这些作业没有按我的意愿工作。尤其是那一行
pointerMatrix[index] = &pointersToIndices.back();
似乎失败了,因为在循环结束时pointerMatrix
的所有元素都指向pointersToIndices
的最后一个条目,而不是正确的条目。
我希望我能澄清这个问题。 有什么建议么? 非常感谢。
【问题讨论】:
“有什么建议吗?” 是的。不要使用指针。另外,帮助自己编写一个可以测试的好的矩阵类。然后,用它来做任何你想做的事情。 如果你非常关心速度,你真的应该在一个分配中布局所有矩阵数据,这样内存就不会碎片化。使用矩阵库可能会帮助您更快地完成任务。例如,“Eigen”或 boost lib 也有 1 或 2 个矩阵库。并且还要避免使用原始指针——如果你是一个学习者,这不是一个好主意。 如果 push_back 调整向量的大小,则指向向量的指针无效。为什么不存储索引而不是指针? 添加到稻田的评论:为什么不存储坐标?毕竟,这是一个矩阵。它还将消除pointersToIndices
。
@MikaProuk 我并没有真正明白你的意思,但是拥有一个矩阵和坐标大约相当于拥有该矩阵中元素的地址,只是更具可读性、直观性和健壮性。跨度>
【参考方案1】:
问题是pointerToIndices
最终会在它必须增长时重新分配(在多个push_back
s 之后)。这会使指向其元素的指针(例如那些在注释后的行中获取和存储的指针)无效,因此以后使用它们是未定义的行为。
我还没有完全理解你的算法,但要么确保pointersToIndices
不会重新分配(通过预先保留足够的空间),要么避免使用指向其元素的指针。 (或者改变你的算法)。
【讨论】:
现在。我所做的只是将pointersToIndices
的声明更改为vector<int *> pointersToIndices(size);
它有效。但。我为数百万个值保留空间,并且不需要其中的一小部分。这不是很糟糕吗?
@MikaProuk 是的,这听起来不太理想。不过,还有其他数据结构可能会帮助您。我建议您查看std::deque,它在附加到(或删除)任一端时永远不会失效。但也许你可以改变你的算法来使用矩阵/向量索引而不是指针。
@MikaProuk 好吧,它显然为您的程序增加了几兆字节的运行时内存。现在,您可以继续使用它,或者您可以通过不过多处理指针来做得更好。以上是关于为指针向量赋值的主要内容,如果未能解决你的问题,请参考以下文章