缓冲区溢出是否发生在C++字符串中



这是关于C++中的字符串。我已经很久没有碰过 C/C++了;事实上,大约 7 年前,我只在大学的第一年用这些语言编程。

在 C 中保存字符串,我必须创建字符数组(无论是静态的还是动态的,这都无关紧要(。所以这意味着我需要提前猜测数组将包含的字符串的大小。好吧,我在C++中应用了相同的方法。我知道有一个 std::string 类,但我从来没有使用它。

我的问题是,由于我们从未在 std::string 类中声明数组/字符串的大小,因此在写入它时是否会发生缓冲区溢出。我的意思是,在 C 中,如果数组的大小为 10 并且我在控制台上键入了 10 个字符以上,那么额外的数据将被写入到与数组相邻的其他对象的内存位置。使用 cin 对象时,std::string 中会发生类似的事情吗?

使用 std::string 时,我是否必须事先猜测字符串的大小C++?

井!谢谢大家。此页面上没有一个正确的答案(提供了许多不同的解释(,所以我不会选择任何一个这样的答案。我对前 5 个感到满意。当心!

根据您用于访问string对象的成员,是的。因此,例如,如果您在pos > size()的地方使用reference operator[](size_type pos),是的,您会的。

假设标准库实现中没有错误,没有。 std::string始终管理自己的内存。

当然,除非您破坏std::string提供的访问器方法,并执行以下操作:

std::string str = "foo";
char *p = (char *)str.c_str();
strcpy(p, "blah");

你在这里没有保护,并且正在调用未定义的行为

std::string 通常可防止缓冲区溢出,但仍存在编程错误可能导致缓冲区溢出的情况。虽然当操作引用字符串边界之外的内存时C++通常会引发out_of_range异常,但下标运算符 [](不执行边界检查(不会

将 std::string 对象转换为 C 样式字符串时会出现另一个问题。如果使用 string::c_str(( 进行转换,则会得到一个正确以 null 结尾的 C 样式字符串。但是,如果使用 string::d ata((,它将字符串直接写入数组(返回指向数组的指针(,则会得到一个不以 null 结尾的缓冲区。 The only difference between c_str() and data() is that c_str() adds a trailing null byte.

最后,许多现有的C++程序和库都有自己的字符串类。若要使用这些库,可能必须使用这些字符串类型或不断来回转换。在安全性方面,此类库的质量参差不齐。通常最好使用标准库(如果可能(或理解所选库的语义。一般来说,库的评估应基于其使用的难易程度或复杂程度、可能产生的错误类型、这些错误的容易程度以及可能产生的潜在后果。请参阅 https://buildsecurityin.us-cert.gov/bsi/articles/knowledge/coding/295-BSI.html

在c中,原因解释如下:

void function (char *str) {
       char buffer[16];
       strcpy (buffer, str);
    }
    int main () {
      char *str = "I am greater than 16 bytes"; // length of str = 27 bytes
      function (str);
    }

此程序肯定会导致意外行为,因为 27 字节的字符串 (str( 已复制到仅分配了 16 个字节的位置(缓冲区(。额外的字节经过缓冲区并覆盖为 FP、返回地址等分配的空间。这反过来又会损坏进程堆栈。用于复制字符串的函数是 strcpy,它不完成边界检查。使用 strncpy 可以防止堆栈的这种损坏。但是,这个经典示例表明缓冲区溢出可以覆盖函数的返回地址,这反过来又可以更改程序的执行路径。回想一下,函数的返回地址是内存中下一条指令的地址,该指令在函数返回后立即执行。

这是一个很好的教程,可以给你满意的答案。

在C++中,std::string类以最小大小开始(或者您可以指定起始大小(。 如果超过该大小,std::string将分配更多的动态内存。

假设提供std::string的库已正确写入,则不能通过向std::string对象添加字符而导致缓冲区溢出。

当然,库中的错误并非不可能。

"C++代码中会发生缓冲区溢出吗?">

在某种程度上,C程序是合法C++代码(它们几乎都是(,C程序有缓冲区溢出,C++程序都有缓冲区溢出。

比 C 更丰富,我相信C++可以以 C 无法的方式出现缓冲区溢出:-}

最新更新