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

C++字符串和流缓冲区溢出安全吗?,c++,overflow,buffer,iostream,C++,Overflow,Buffer,Iostream,如果我使用std::cin、std::cout和std::string,是否有人会利用缓冲区溢出进行攻击 我问这个问题,因为我仍然看到很多人仍然使用零结尾字符串代替C++中的标准容器。< P>仍然有很多人使用空终止字符串,因为它们没有实现使用STD::string的便利性,它们实际上是编写过程C++而不是C++。p> 大多数程序员从C迁移到C++是使用空终止字符串的程序。 它非常安全,你应该在任何地方使用STD::C++中的字符串。 std:string实际上保护您不受缓冲区溢出的影响,这与c字

如果我使用std::cin、std::cout和std::string,是否有人会利用缓冲区溢出进行攻击


我问这个问题,因为我仍然看到很多人仍然使用零结尾字符串代替C++中的标准容器。

< P>仍然有很多人使用空终止字符串,因为它们没有实现使用STD::string的便利性,它们实际上是编写过程C++而不是C++。p> <>大多数程序员从C迁移到C++是使用空终止字符串的程序。 它非常安全,你应该在任何地方使用STD::C++中的字符串。 std:string实际上保护您不受缓冲区溢出的影响,这与c字符串不同,它是随着添加到字符串中的数据的增加而动态增大的

安:

输出:

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


一个重要的原因,你还可以看到人们在C++中使用C字符串,除了不知道字符串,或者被困在C心态中,就是STD::istRAM::GETLIN使用char指针而不是字符串。图书馆的许多其他部分也是如此。这样做的部分原因是,你不用为你不用的东西付费。IE:只想获取一行文本的人不必实例化一个字符串,因此也必须拉入另一个模板类来实现。如果需要,可以使用std::getline将行作为字符串获取,但这并不明显。所以有些人认为他们仍然需要使用字符缓冲区来获得一行文本

在C++11中,这一点似乎发生了很大的变化,您可以在以前必须传递char*的许多地方使用字符串。也许这会对C++中的C问题有所帮助


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

视情况而定。当然,当您使用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

C字符串可能更快,因为std容器必须支持它们所支持的某些功能。所以,没有人可以指出最好的选择。

很多人都没有在C++中编码——他们用C++编译C代码。很多人相信他们在C++中编码时,实际上是在C的一个子集中编码。如果你正确使用,那么,不,但是,任何事情都可以这样说,你可以说,与C-Stringstd::vector v相比,错误地使用std::string更难;“那看起来很烦人。”詹姆斯奈利斯:爬到角落里。我只是希望你能看到,由于将第一个片段编辑成第二个片段,所以发生了这种情况……我明白了。这意味着,如果我在上对向量和字符串使用边界检查,就不会有人以不同的方式利用缓冲区溢出。谢谢。嗯,我不确定结论。如果您正确地使用了所有内容,那么唯一可能的错误应该是分配错误,它通过异常发出信号。所以你不需要任何的如果和但是。你的程序仍然有可能遭到拒绝服务,比如说,如果它在一台只有4GB物理RAM的机器上请求20GB,那么这个程序仍然是完全正确的,但可能会迫使操作系统屈服。但是这超出了安全编程的范围。@milleniumbug:另外,我想说的一点不是边界检查,而是避免预先分配固定大小。std::back\u inserterv有效地调用v.push\u back。。。这是完全安全的——根本不是真的,见sehe的例子。如果避免访问超出范围的字符串,则std::string是安全的,但C样式的字符串也是安全的。区别在于,您不太可能需要担心字符串,但可能性不是零。
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