有一种方法调用foo
有时会返回以下错误:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Abort
Run Code Online (Sandbox Code Playgroud)
有没有我可以用一种方式try
- catch
块从终止我的程序停止这个错误(所有我想要做的就是回报-1
)?
如果是这样,它的语法是什么?
我还能用bad_alloc
C++ 处理什么?
我的程序中有一个相当严重的错误 - 偶尔调用new()会抛出bad_alloc.
从我在bad_alloc上找到的文档中,似乎抛出了以下原因:
当计算机内存不足时(肯定没有发生,我有4GB的RAM,程序在使用少于5MB(在taskmanager中检查)时抛出bad_alloc,后台没有严重的运行).
如果内存变得过于分散而不能分配新的块(这也不太可能 - 我分配的最大块大小约为1KB,并且在崩溃发生之前不会超过100次).
基于这些描述,我真的没有任何可以抛出bad_alloc的地方.
但是,我运行的应用程序运行多个线程,这可能会导致问题.通过测试单个线程上的所有对象,一切似乎都顺利进行.我能想到的另一件事就是在这里发生的某种竞争条件可能是因为同时在多个地方调用new()而引起的,但我尝试添加互斥锁来防止这种行为发生没有效果.
因为该程序是几百行,我不知道问题究竟在哪里,我不知道发布的代码片段是什么(如果有的话).相反,我想知道是否有任何工具可以帮助我测试这种事情,或者是否有任何一般策略可以帮助我解决这个问题.
我正在使用Microsoft Visual Studio 2008,Poco用于线程化.
我有这个代码..
CEngineLayer::CEngineLayer(void)
{
// Incoming creation of layers. Wrapping all of this in a try/catch block is
// not helpful if logging of errors will happen.
logger = new (std::nothrow) CLogger(this);
if(logger == 0)
{
std::bad_alloc exception;
throw exception;
}
videoLayer = new (std::nothrow) CVideoLayer(this);
if(videoLayer == 0)
{
logger->log("Unable to create the video layer!");
std::bad_alloc exception;
throw exception;
}
}
IEngineLayer* createEngineLayer(void)
{
// Using std::nothrow would be a bad idea here as catching things thrown
// from the …
Run Code Online (Sandbox Code Playgroud) 消息:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Run Code Online (Sandbox Code Playgroud)
我查看了gdb backtrace,这是我自己实现的最低级别方法:
/*
* get an array of vec3s, which will be used for rendering the image
*/
vec3 *MarchingCubes::getVertexNormalArray(){
// Used the same array size technique as getVertexArray: we want indices to match up
vec3 *array = new vec3[this->meshPoints.getNumFaces() * 3]; //3 vertices per face
int j=0;
for (unsigned int i=0; i < (this->meshPoints.getNumFaces() * 3); i++) {
realVec normal = this->meshPoints.getNormalForVertex(i);
// PCReal* iter = normal.begin();
if …
Run Code Online (Sandbox Code Playgroud) 我制作了一个类,它使用new
(只是为了好玩!)递归地创建自己,希望std::bad_alloc
由于无限的动态分配(堆溢出)而抛出该类。但是发生堆栈溢出而不是std::bad_alloc
。为什么会这样?
class Overflow
{
private:
Overflow* overflow;
public:
Overflow()
{
overflow = new Overflow();
}
};
int main()
{
Overflow overflow_happens; // stack overflow happens instead of std::bad_alloc exeption
}
Run Code Online (Sandbox Code Playgroud)
@Caleth问如果我将new Overflow()更改为new Overflow [100000],会发生什么,这给了我std::bad_alloc
。根据答案,这岂不是还会给我堆栈溢出吗?
我尝试bad_alloc
通过传递一些否定参数来测试异常new[]
.当传递小的负数时,我得到了我所希望的 - a bad_alloc
.但是,在传递时-1
,我可以看到我的对象构造了数千次(我在构造函数中打印静态计数器),应用程序终止于segfault.
new[]
转换有符号整数size_t
,所以-1
是最大size_t
且-2
是maximum - 1
等.
那么为什么new[]
在接收一些巨大的数字时抛出异常,但是在接收到最大值时会尝试分配size_t
?是什么区别1111...1
,并1111...0
为new[]
?:)
提前致谢!
我有一个程序实现了几个启发式搜索算法和几个域,旨在通过实验评估各种算法.该程序是用C++编写的,使用GNU工具链构建,并在64位Ubuntu系统上运行.当我运行我的实验时,我使用bash的ulimit
命令来限制进程可以使用的虚拟内存量,以便我的测试系统不会开始交换.
某些算法/测试实例组合达到了我定义的内存限制.大多数情况下,程序抛出一个std :: bad_alloc异常,由异常处理程序打印,此时程序终止.偶尔,程序只是段错误而不是这种情况发生.
为什么我的程序在内存不足时偶尔会出现段错误,而不是报告未处理的std :: bad_alloc并终止?
我有一个程序失败:
terminate called after throwing an instance of 'std::bad_alloc'
what(): St9bad_alloc
Run Code Online (Sandbox Code Playgroud)
我想这与malloc
/有关free
,但我不知道哪一个.
我可以在gdb中设置什么断点来破坏错误,以便我可以查看堆栈跟踪?
该程序是C和C++的组合,使用gcc 3.4.2编译.
假设您拥有通常永远不会失败的功能,例如:
std::string convert_integer_to_string(int x);
Run Code Online (Sandbox Code Playgroud)
在市政当局,这将是一个候选人noexcept
.但是,实现最有可能涉及动态内存管理,因此在为运算符分配内存时,它总是会抛出std :: bad_allocnew
.
是否建议将该函数注释为noexcept?
从实际的角度来看,以合理的方式处理内存不足的情况是极其困难的.大多数程序只假设有足够的可用内存.std::terminate
正如在某个noexcept
函数抛出时所发生的那样,调用std::bad_alloc
在这种情况下似乎是合理的.
对我来说noexcept
是某种形式的文档.这是一个承诺,你(或优化器)可以安全地假设这个函数永远不会抛出.如果您正在编写一个不关心内存不足情况的应用程序,那么它仍然是一个有效的假设.
我想最安全的建议是noexcept
如果std::bad_alloc
抛出异常就永远不要使用.另一方面,我想知道是否有优势可以使用noexcept
,假设您不关心内存不足的情况(即,如果std::terminate
可以).
据我所知,有三个原因可以抛出std :: bad_alloc:
我们有运行到std :: bad_alloc的代码,但上述原因似乎都不适用.数据结构是一个存储为std :: verts列表的图形,其中每个顶点再次存储std :: list的边缘列表,以及一些连续数据.
对于小图形(<= 100'000个顶点),程序运行完全正常,无论每个顶点的数据部分有多大(我们可以毫无问题地分配最多40 GB).但是,如果顶点的数量变大,即使在使用"仅"8 GB内存的实例上,我们也会抛出std :: bad_alloc异常.
由于在较大的块中分配更多内存时没有问题,因此应排除上述原因1.和2. 有一些部分我们以极易出错的方式使用指针,因此我们可能会破坏堆数据结构.但是当在较小的实例上运行时,valgrind的memcheck会将我们的代码报告为完美无缺,因此理由似乎也不太可能(在抛出实例时,valgrind本身会耗尽内存,所以我们无法直接检查这种情况).
是否有任何关于这种行为可能是什么原因的想法,或者我们可能会进行哪些测试来进一步确定问题?
操作系统:Fedora 19
构建系统:cmake与gcc 4.8.2