在Linux上,如果内存不足,malloc不一定返回空指针.你可能会找回一个指针然后让OOM杀手开始吃进程,如果你真的没有记忆.c ++的operator new也是如此,你会得到bad_alloc异常吗?
如果失败,我知道做一个new(std::no_throw)
会设置指针NULL
.我也知道普通new
会std::bad_alloc
在失败时抛出异常.
如果它抛出,法线new
还会设置指针NULL
吗?或者我应该将其设置NULL
为catch()
块?
我需要澄清一个我不太了解的问题.使用下面的两个场景,我会认为分配的内存量大致相同.但是,方案2 bad_alloc
在一段时间后给了我一个例外,并且似乎像疯了一样咀嚼内存(使用Window的任务管理器作为分配给进程的内存量的代理).以下是使用MSVC10在Windows 32位上编译的.
假设我有以下基类:
template<class T>
class Base
{
protected:
T x;
public:
Base() {}
Base(T _x) : x(_x){}
virtual bool func() = 0;
};
Run Code Online (Sandbox Code Playgroud)
现在,至于派生类:
template<class T>
class Derived : public Base<T>
{
public:
Derived() {}
Derived(T _x) : Base(_x){}
bool func() { return true; };
};
Run Code Online (Sandbox Code Playgroud)
现在考虑两种情况.首先,分配Derived类的动态数组并用Derived对象填充它,即:
int main()
{
int size = SOME_LARGE_NUMBER;
Derived<int>* d = new Derived<int>[size];
for (int i = 0; i < size; i++)
{
d[i] = Derived<int>(i);
}
// delete here
} …
Run Code Online (Sandbox Code Playgroud) 这可能是愚蠢的事,但我无法弄清楚.我std::bad_alloc
在以下代码片段中获得异常(这是交换机中的case语句):
case 0:
{
MyPrimitiveNode* node = new MyPrimitiveNode( 1, false );
TheStack.push_back( MyStackItem( node, TYPE_REF ) ); // bad_alloc here
break;
}
Run Code Online (Sandbox Code Playgroud)
TheStack
类型在哪里MyStack
,哪个是typedef std::vector<MyStackItem> MyStack;
MyStackItem
是一个简单的结构,看起来像这样:
struct MyStackItem {
MyNode* value;
uint8_t type;
MyStackItem() {
value = NULL;
type = TYPE_UNDEF;
}
MyStackItem( MyNode* val, uint8_t t ) {
value = val;
type = t;
}
};
Run Code Online (Sandbox Code Playgroud)
至于MyNode
nad MyPrimitiveNode
,它们来自另一个项目(静态库),定义如下:
class MyNode
{
public:
MyNode() {}
virtual ~MyNode() {}
}; …
Run Code Online (Sandbox Code Playgroud) 对不起我的一般性问题,但我找不到明确的答案:
鉴于我有剩余的免费交换内存并且我以合理的块(~1MB)分配内存 - >内存分配是否因任何原因仍然失败?
我正在使用32位Ubuntu 12.04.RAM为7.7 GB.当我运行某个进程(用C++编写)并达到50%的RAM使用率时,这样的进程会抛出一个"std :: bad_alloc".奇怪的是,堆的大小是无限的(命令的ulimit -v返回"unlimted").那可能是什么原因?
我有一个C++应用程序,它终止了AIX机器上某些输入数据的"错误分配"错误消息.
有没有办法在dbx中运行程序并在抛出异常时捕获异常?我在IBM的文档中没有看到任何相关内容.
我正在尝试读取大小为 ~1.1GB 的 .dat 文件中包含的数据。因为我是在 16GB RAM 的机器上执行此操作,所以我认为将整个文件一次读入内存不会有问题,只有在处理它之后。
为此,我使用了slurp
在这个 SO answer 中找到的函数。问题是代码有时(但并非总是)抛出 bad_alloc 异常。查看任务管理器,我发现总有至少 10GB 的可用内存可用,所以我不知道内存会是什么问题。
这是重现此错误的代码
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
ifstream file;
file.open("big_file.dat");
if(!file.is_open())
cerr << "The file was not found\n";
stringstream sstr;
sstr << file.rdbuf();
string text = sstr.str();
cout << "Successfully read file!\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
什么可能导致这个问题?避免它的最佳做法是什么?
在我们的应用程序中,我们将任何崩溃记录到包含堆栈跟踪的日志文件中.我们可以使用这些报告来确定崩溃原因.
问题是,我们倾向于在几个地方(实际上很多)捕获std :: exception,这使得在抛出bad_alloc时报告实际上没用,因为堆栈跟踪丢失了.
如何更改行为,所以程序中止而不是抛出bad_alloc?当我们在3个不同的操作系统中编写时,使用3个不同的std实现,改变std本身是我们想要避免的.
当bad_alloc
在构造函数中抛出异常时,在该构造函数中创建了多个对象,必须采取什么措施来清理内存.防爆.
class Object
{
private:
A * a;
B * b;
public:
Object()
{
a= new A();
b= new B(); //So if a bad_alloc is called here, how is a deleted???
}
}
Run Code Online (Sandbox Code Playgroud)
我的直觉是将每个调用new放在一个单独的try catch块中,并删除new
之前调用过的所有对象,但这太冗长了(第一次尝试bloc不调用析构函数,第二次调用第一次调用,第三次调用前两个等).我的问题是:处理这个问题最常见的方法是什么?
另外,假设类对象包含一个不是用new创建的对象(因为它在栈中),它的析构函数是自动调用的吗?
bad-alloc ×10
c++ ×9
exception ×2
new-operator ×2
aix ×1
allocation ×1
constructor ×1
dbx ×1
debugging ×1
file-io ×1
linux ×1
memory ×1
null ×1
pointers ×1
polymorphism ×1
stl ×1
swap ×1
vector ×1
windows ×1