EXC_BAD_ACCESS使用<<在stringstream对象

时间:2017-05-18 13:13:09

标签: c++ string stringstream

我正在编写一个代码,我需要在内存中写入一个大字符串。 我使用了一个stringstream对象来执行此操作,但发生了一些奇怪的事情:即使底层字符串缓冲区的大小未超过字符串对象的最大大小,我的程序也会因BAD_ACCESS错误而崩溃。

我已经创建了一个这样的测试程序:

#include <sstream> // std::stringstream
#include <iostream> // std::cout

int main(int argc, const char * argv[]) {

    std::stringstream stream;
    std::string string;
    std::cout << "Max string size: " << string.max_size() << "\n";

    for (int i = 0; true; i++) {
        if (i >= 644245094) {
            stream.seekg(0, std::ios::end);
            std::stringstream::pos_type size = stream.tellg();
            stream.seekg(0, std::ios::beg);
            std::cout << "Size of stringstream: " << size << "\n";
        }
        stream << "hello";
    }

    return 0;
}

循环中的if (i >= 644245094)仅用于在程序崩溃之前打印字符串流缓冲区的大小。我已经使用我的调试器来查看最后一次迭代的数量,并在崩溃发生之前用它来打印缓冲区的大小。

这是我得到的输出:

Max string size: 18446744073709551599
Size of stringstream: 3221225470

此后程序崩溃。

我认为原因可能是因为程序填满了计算机的RAM,但是这个程序使用的内存大约是6.01GB,所以还不足以填满我的RAM。为了记录,我有一个16GB的RAM Macbook Pro。

可能是什么问题?我错过了<<运算符的工作方式吗?

提前谢谢!

1 个答案:

答案 0 :(得分:1)

std :: stringstream充满并失败时的行为可能在所有平台上都不一致。

我修改了你的代码并使用gcc 5.4.1在Yocto 3.19.0-32 64位上下载它。我没有抛出异常,而是设置了一个故障模式位。

我跑的代码是:

#include <sstream>    // std::stringstream
#include <iostream>   // std::cout

std::stringstream::pos_type get_size(std::stringstream& stream)
{
    stream.seekg(0, std::ios::end);
    std::stringstream::pos_type size = stream.tellg();
    stream.seekg(0, std::ios::beg);
    return size;
}

int main(int argc, const char * argv[])
{
    std::stringstream stream;
    std::string string;
    std::cout << "Max string size: " << string.max_size() << std::endl;
    std::stringstream::pos_type size;

    for (unsigned long i = 0; true; ++i)
    {
        size = get_size(stream);
        stream.write("x", 1);
        if (stream.fail())
        {
            std::cout << "Fail after " << i + 1 << " insertions" << std::endl;
            std::cout << "Size of stringstream just before fail: " << size << std::endl;
            break;
        }
    }

    size = get_size(stream);
    std::cout << "Size of stringstream just after fail: " << size << std::endl;

    return 0;
}

我得到了以下输出,显示我的字符串流填充并且失败56字节短8GB:

Max string size: 4611686018427387897
Fail after 8589934536 insertions
Size of stringstream just before fail: 8589934535
Size of stringstream just after fail: -1

你能否使用不同的容器并预先分配内存,而不是使用这么大的字符串流?