是 C++字符串和流缓冲区溢出安全吗?

发布于 2024-12-13 12:40:53 字数 112 浏览 1 评论 0原文

如果我使用 std::cin、std::cout 和 std::string,是否有可能有人利用缓冲区溢出?

我问这个问题是因为我仍然看到很多人仍然使用空终止字符串而不是 C++ 中的标准容器。

If I use std::cin, std::cout and std::string, is there any possibility that someone will exploit the buffer overflow?

I ask this because I still see a lot of people that still use null-terminated strings instead of standard containers in C++.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

轻拂→两袖风尘 2024-12-20 12:40:53

您仍然看到人们在 C++ 中使用 C 字符串(除了不了解字符串或陷入 C 思维模式之外)的一大原因是 std::istream::getline 与 char 一起使用指针而不是字符串。图书馆的许多其他部分也是如此。部分原因是“你不用为不使用的东西付费”。 IE:只想获取一行文本的人不必实例化一个字符串(因此还必须引入另一个模板类)来执行此操作。如果需要,您可以使用 std::getline 来获取字符串形式的行,但这并不明显。所以有些人认为他们仍然需要使用字符缓冲区来获取一行文本。

(在 C++11 中似乎发生了很多变化,并且您可以在以前必须传递 char* 的很多地方使用 string。也许这将对 C-in-C++ 问题有所帮助。)

标准字符串和流被设计为防溢出,并且比 char 指针更安全(至少在不使用它们时) 就像一个普通的旧数组/指针一样盲目使用; str 的迭代器不考虑 str.end() 通常是一个坏主意,但是 str.push_back(), str += "text"str.at(x) 和流插入/提取运算符是完全安全的)。如果您可以使用它们,我强烈建议您这样做。

One of the big reasons you still see people using C-strings in C++ (besides not knowing about strings, or being stuck in a C mindset), is that std::istream::getline works with char pointers and not strings. As do a huge number of other parts of the library. Part of the reason for that was so that "you don't pay for what you don't use". IE: people that just want to get a line of text shouldn't have to instantiate a string (thereby also having to pull in another template class) to do so. You can use std::getline to get lines as strings if you want them, but that's not obvious. So some people think they still need to use char buffers to get a line of text.

(Seems a lot of that is changed in C++11, and you can use strings in a lot of places where you had to pass a char* before. Maybe that'll help a bit with the C-in-C++ problem.)

Standard strings and streams are designed to be overflow-resistant, and are all-around safer than a char pointer (at least when they're not used like a plain old array/pointer; blindly using str's iterator without regard for str.end() is usually a bad idea, but str.push_back(), str += "text", str.at(x), and stream insertion/extraction operators are perfectly safe). If you can use them, i highly recommend you do so.

枫林﹌晚霞¤ 2024-12-20 12:40:53

仍然有很多人使用以 null 结尾的字符串,因为他们没有意识到使用 std::string 的便利性,而且他们实际上是在编写过程式 C++,而不是 C++。

大多数从 C 迁移到 C++ 的程序员仍然使用以 null 结尾的字符串。

它是完全安全的,你应该尽可能在 c++ 中使用 std::string

std:string 实际上通过随着添加到其中的数据的增加而动态增加大小来防止缓冲区溢出(与 C 字符串不同)。

代码示例

#include <iostream>
using namespace std;

int main()
{
    string str("std::String");
    for (int i=0; i<20; ++i)
    {
        cout << "capacity is " << str.capacity() << endl;
        str += " ,is Overrun safe string";
    }
    return 0;
}

输出:

容量为11
容量为35
容量为70
容量为140
容量为140
容量为140
容量为280
容量为280
容量为280
容量为280
容量为280
容量为280
容量为560
容量为560
容量为560
容量为560
容量为560
容量为560
容量为560
容量为 560

Still lot of people use null-terminated strings because they do not realize the convenience of using std::string and they are really writing procedural c++ not c++.

Most programmers migrating/migrated from c to c++ are the ones who still use null-terminated strings.

It is perfectly safe and you should use std::string in c++ wherever you can.

std:string actually protects you against buffer overflow(unlike c strings) by dynamically growing in size as the data added to it is increased.

An code sample:

#include <iostream>
using namespace std;

int main()
{
    string str("std::String");
    for (int i=0; i<20; ++i)
    {
        cout << "capacity is " << str.capacity() << endl;
        str += " ,is Overrun safe string";
    }
    return 0;
}

Output:

capacity is 11
capacity is 35
capacity is 70
capacity is 140
capacity is 140
capacity is 140
capacity is 280
capacity is 280
capacity is 280
capacity is 280
capacity is 280
capacity is 280
capacity is 560
capacity is 560
capacity is 560
capacity is 560
capacity is 560
capacity is 560
capacity is 560
capacity is 560

笑红尘 2024-12-20 12:40:53

这取决于。当然,当您使用 C 风格代码/API 时,没有区别

但使用 STL 或 C++ 习惯用法并不能保证您的安全。

C++ 始终为您提供选择。对比这两个几乎相同的双胞胎:

int n;
std::cin >> n;
std::string s(n, '*'); // create a data store of given size

std::vector<char> v(1000);
std::copy(s.begin(), s.end(), v.begin()); // NOT safe if n > 1000

安全变体:

int n;
std::cin >> n;
if (n > MAX_LIMIT) 
    throw std::runtime_error("input too large");
std::string s(std::min(0, n), '*'); // note input sanitation

std::vector<char> v;
v.reserve(1000);
std::copy(s.begin(), s.end(), std::back_inserter(v)); // safe

It depends. Of course, when you use C-style code/API's, there is no difference.

But using STL or C++ idioms doesn't guarantee that you're safe.

C++ gives you the choice, always. Contrast these two near-identical twins:

int n;
std::cin >> n;
std::string s(n, '*'); // create a data store of given size

std::vector<char> v(1000);
std::copy(s.begin(), s.end(), v.begin()); // NOT safe if n > 1000

safe variant:

int n;
std::cin >> n;
if (n > MAX_LIMIT) 
    throw std::runtime_error("input too large");
std::string s(std::min(0, n), '*'); // note input sanitation

std::vector<char> v;
v.reserve(1000);
std::copy(s.begin(), s.end(), std::back_inserter(v)); // safe
单身狗的梦 2024-12-20 12:40:53

C 字符串可能更快,因为 std 容器必须支持它们支持的某些功能。因此,没有人能指出任何时候的最佳选择。

C-strings may be faster, because std containers have to support some functionality that they support. So, nobody can point the best choice for all times.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文