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

时间:2012-05-01 13:13:45

标签: c++ string buffer-overflow

这与C ++中的字符串有关。我很长时间没有接触过C / C ++;事实上,大约7年前,我只在大学的第一年用这些语言编程。

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

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

在使用std :: string?

时,我是否必须在C ++中猜测字符串的大小

嘛!谢谢大家。这个页面上没有一个正确的答案(提供了很多不同的解释),所以我没有选择任何一个这样的答案。我很满意第一个5.小心!

6 个答案:

答案 0 :(得分:8)

取决于您用来访问string对象的成员,是的。因此,例如,如果您使用reference operator[](size_type pos) pos > size(),那么您可以。

答案 1 :(得分:6)

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

当然,除非您颠覆std::string提供的访问者方法,并执行以下操作:

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

此处您没有任何保护,并且正在调用未定义的行为

答案 2 :(得分:3)

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

将std :: string对象转换为C风格的字符串时,会发生另一个问题。如果使用string :: c_str()进行转换,则会得到一个正确的以null结尾的C风格字符串。但是,如果使用string :: data(),它会将字符串直接写入数组(返回指向数组的指针),得到一个非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

原因如下:

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可以防止堆栈的这种损坏。但是,这个经典的例子表明缓冲区溢出可以覆盖函数的返回地址,这反过来可以改变程序的执行路径。回想一下函数的返回地址是内存中下一条指令的地址,它在函数返回后立即执行。

这是good tutorial,可以让您的答案令人满意。

答案 3 :(得分:2)

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

答案 4 :(得分:1)

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

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

答案 5 :(得分:0)

“C ++代码中是否出现缓冲区溢出?”

如果C程序是合法的C ++代码(它们几乎都是),并且C程序有缓冲区溢出,C ++程序可能会有缓冲区溢出。

比C更富有,我确信C ++可以以C不能的方式出现缓冲区溢出: - }