你写了mSectionsSubsets[i] 和i 从0 到count。
这些访问中的每一个都是非法的,因为mSectionsSubsets 中没有任何元素。
保留容量和调整向量大小是两件不同的事情。
在这种特殊情况下,也许:
mSectionsSubsets.resize(count);
for (int i = 0; i < count; i++) {
mSectionsSubsets[i].reserve(NUM_SECTIONS);
}
但是,总体而言,我会警告不要使用向量的向量:它们对您的缓存有害,而且当您的尺寸为方形时通常不需要。
换个漂亮的std::vector<int> 怎么样?如果您需要 count*NUM_SECTIONS 元素,那么只需执行此操作。您始终可以为其索引创建二维外观:
i = x + width*y
缓存来自 cmets 的快速模型:
#include <iostream>
#include <vector>
#include <stdexcept>
#include <cassert>
// Like a vector<vector<T>>, but *better*!
template <typename T>
class RowList
{
public:
RowList(const std::size_t rowCount, const std::size_t maxRowLength)
: rowCount(rowCount)
, maxRowLength(maxRowLength)
, data(rowCount * maxRowLength)
, utilisation(rowCount)
{}
std::size_t getRowCount() const
{
return rowCount;
}
std::size_t getMaxRowLength() const
{
return maxRowLength;
}
// UB if you give an invalid row number
std::size_t getRowLength(const std::size_t rowNumber) const
{
assert(rowNumber < rowCount);
return utilisation[rowNumber];
}
// UB if you give an invalid row number
void clearRow(const std::size_t rowNumber)
{
assert(rowNumber < rowCount);
utilisation[rowNumber] = 0;
#ifdef NDEBUG
// Debug builds only - make all the dead values -1
// so we can maybe more easily spot misuse
const std::size_t start = rowNumber*maxRowLength;
const std::size_t end = start + maxRowLength;
for (std::size_t i = start; i < end; ++i)
data[i] = -1;
#endif
}
// UB if you give an invalid row number
// throws std::out_of_range if the row is full
void pushToRow(const std::size_t rowNumber, T value)
{
assert(rowNumber < rowCount);
std::size_t& columnNumber = utilisation[rowNumber];
if (columnNumber == maxRowLength)
throw std::out_of_range("Row is full!");
data[rowNumber*maxRowLength + columnNumber] = std::move(value);
columnNumber++;
}
// UB if you give an invalid row or column number
T& elementAt(const std::size_t rowNumber, const std::size_t columnNumber)
{
assert(rowNumber < rowCount);
assert(columnNumber < utilisation[rowNumber]);
return data[rowNumber*maxRowLength + columnNumber];
}
// UB if you give an invalid row or column number
const T& elementAt(const std::size_t rowNumber, const std::size_t columnNumber) const
{
assert(rowNumber < rowCount);
assert(columnNumber < utilisation[rowNumber]);
return data[rowNumber*maxRowLength + columnNumber];
}
private:
const std::size_t rowCount;
const std::size_t maxRowLength;
std::vector<T> data;
std::vector<std::size_t> utilisation;
};
template <typename T>
std::ostream& operator<<(std::ostream& os, const RowList<T>& matrix)
{
const auto height = matrix.getRowCount();
for (std::size_t y = 0; y < height; ++y)
{
const auto width = matrix.getRowLength(y);
const auto remainder = matrix.getMaxRowLength() - width;
for (std::size_t x = 0; x < width; ++x)
os << matrix.elementAt(y, x) << '\t';
for (std::size_t i = 0; i < remainder; ++i)
os << "?\t";
os << '\n';
}
return os;
}
int main()
{
RowList<int> matrix(5, 5);
matrix.pushToRow(2, 100);
matrix.pushToRow(2, 101);
matrix.pushToRow(4, 102);
std::cerr << matrix << '\n';
matrix.clearRow(2);
matrix.pushToRow(1, 103);
std::cerr << matrix << '\n';
}
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
? ? ? ? ?
? ? ? ? ?
100 101 ? ? ?
? ? ? ? ?
102 ? ? ? ?
? ? ? ? ?
103 ? ? ? ?
? ? ? ? ?
? ? ? ? ?
102 ? ? ? ?