我正在尝试创建一个防缓冲区溢出的程序,并且我正在考虑为此使用stl向量,但是我已经读到它仍然不会执行边界检查并且仍然会被黑客入侵。我主要担心重写程序中的返回或函数调用或其他变量。在这种情况下,矢量会起作用吗?
您可以这样声明一个向量
std::vector<int> v;
这是vector
的空int
,称为v
。它有0个元素。尝试访问其任何元素都是未定义的行为。因此,是的,如果处理不当,有可能在std::vector
中创建缓冲区溢出。
v[0] = 1; // undefined because we're out of bounds
v[1] = 2; // as is this
[通常在将元素添加到std::vector
时使用push_back
或emplace_back
,但不直接访问元素
v.push_back(0); // v is now 1 element long: { 0 }
v.emplace_back(1); // v is now 2 elements long: { 0 , 1 }
使用[]
运算符does为您提供对基础项目的引用,因此,只要您确定索引有效,就可以将其用于检索和分配。您可以使用size()
函数来确定适当的最大元素索引是什么(size() - 1
)
for (std::size_t i = 0; i < v.size(); ++i)
{
v[i] = 10;
}
// v was size 2, we've replaced both elements at 0 and 1 with value 10
使用std::vector
时,请使用提供给您的界面。使用push_back
或emplace_back
或insert
添加元素。 pop_back
或erase
删除元素。 std::vector
知道其begin
和end
,因此您可以像这样遍历它:
// prints the elements in the vector
for (auto it = v.begin(); it != v.end(); ++it)
std::cout << *it << " ";
std::cout << "\n";
或基于范围的for循环,因为它提供了begin()
和end()
函数
// prints the elements in the vector
for (const auto& elem : v)
std::cout << elem << " ";
std::cout << "\n";
可能会溢出std::vector
缓冲区,但如果遵循规则,则可能性很小。 std::vector
比数组更好,因此,如果您不介意免费存储中存在的元素(这是大多数非高性能应用程序),那么就去吧。易用性和灵活性非常值得额外的开销。
此外,由于std::vector
中的数据不存在于堆栈中(而在堆栈上放置了本地数组时),如果您确实超出了std::vector
,则您不太可能覆盖堆栈。如果幸运的话,您的程序将崩溃,但不要依赖于此。
总之,std::vector
的缓冲区可能会溢出,但是它的接口很难做到这一点。如果您确实超负荷了它的缓冲区,那么您将覆盖免费存储中的数据,而不是堆栈中的数据,因此您将不会修改返回地址。尽管您可能会通过vector
缓冲区溢出来覆盖免费存储中的第二个项目,但我认为这是不确定的。尽管任何人都可以使用数组访问您的源代码,但可以轻松确定哪些输入将产生堆栈覆盖(如果有)。
有关https://en.cppreference.com/w/cpp/container/vector界面的更多信息,请参见std::vector
。