EXC_BAD_ACCESS 在字符串流对象上使用 <<
EXC_BAD_ACCESS using << on stringstream object
我正在编写代码,需要将一个大字符串写入内存。
我使用了一个 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)
仅用于在程序崩溃之前打印 stringstream 缓冲区的大小。我已经使用我的调试器查看最后一次迭代的次数,并在崩溃发生之前用它来打印缓冲区的大小。
这是我得到的输出:
Max string size: 18446744073709551599
Size of stringstream: 3221225470
此后程序崩溃。
我认为原因可能是因为该程序填满了我计算机的 RAM,但该程序使用的内存约为 6.01GB,因此不足以填满我的 RAM。作为记录,我有一台 16GB 内存的 Macbook Pro。
可能是什么问题?我是否遗漏了一些关于 <<
运算符如何工作的信息?
提前致谢!
std::stringstream 满载和失败时的行为在所有平台上可能不一致。
我修改了你的代码,并在 Yocto 3.19.0-32 64 位,gcc 5.4.1 上运行。我没有抛出异常,而是流设置了它的故障模式位之一。
我 运行 的代码是:
#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
你能不能不使用不同的容器并预先分配内存,而不是使用这么大的字符串流?
我正在编写代码,需要将一个大字符串写入内存。
我使用了一个 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)
仅用于在程序崩溃之前打印 stringstream 缓冲区的大小。我已经使用我的调试器查看最后一次迭代的次数,并在崩溃发生之前用它来打印缓冲区的大小。
这是我得到的输出:
Max string size: 18446744073709551599
Size of stringstream: 3221225470
此后程序崩溃。
我认为原因可能是因为该程序填满了我计算机的 RAM,但该程序使用的内存约为 6.01GB,因此不足以填满我的 RAM。作为记录,我有一台 16GB 内存的 Macbook Pro。
可能是什么问题?我是否遗漏了一些关于 <<
运算符如何工作的信息?
提前致谢!
std::stringstream 满载和失败时的行为在所有平台上可能不一致。
我修改了你的代码,并在 Yocto 3.19.0-32 64 位,gcc 5.4.1 上运行。我没有抛出异常,而是流设置了它的故障模式位之一。
我 运行 的代码是:
#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
你能不能不使用不同的容器并预先分配内存,而不是使用这么大的字符串流?