C++ std::bad_alloc没有在任何调用堆栈帧中被捕获

C++ std::bad_alloc没有在任何调用堆栈帧中被捕获,c++,try-catch,bad-alloc,C++,Try Catch,Bad Alloc,如果新操作符无法分配内存,只有在新语句周围立即放置try-catch块时,才会捕获异常std::bad_alloc。如果我在下面几帧的调用程序中使用try-catch块,它就不会在那里被捕获,我会得到一个异常的程序术语。为什么会发生这种情况?这是在MicrosoftVisualStudio2008上 编辑:好的,这是不起作用的代码。下面的函数是我调用new的地方,下面的是它下面的stackframes。最后一个函数是我有catch子句的地方,但是它没有在那里被捕获 void HTTPRespon

如果新操作符无法分配内存,只有在新语句周围立即放置try-catch块时,才会捕获异常std::bad_alloc。如果我在下面几帧的调用程序中使用try-catch块,它就不会在那里被捕获,我会得到一个异常的程序术语。为什么会发生这种情况?这是在MicrosoftVisualStudio2008上

编辑:好的,这是不起作用的代码。下面的函数是我调用new的地方,下面的是它下面的stackframes。最后一个函数是我有catch子句的地方,但是它没有在那里被捕获

void HTTPResponseBuff::grow()
{
    if (m_nMaxSize > m_nStartConstGrowSize)
        m_nMaxSize += m_nConstGrowSize;
    else
        m_nMaxSize = 2 * m_nMaxSize;

    char* pTmp = new char[m_nMaxSize];
    . . . 
}

void HTTPResponseBuff::write(const char* pBuf, size_t len)
{
    char* pCh;
    while (getRemainingCapacity(pCh) < len)
        grow();
    . . . 
}

size_t HTTPTransport::responseCallback(void *pRespData, size_t size,
                             size_t nmemb, void *pRespBuff)
{
    const char* pChar = (const char*)pRespData;
    register int respDataLen = size * nmemb;    
    ((HTTPResponseBuff*)pRespBuff)->write(pChar, respDataLen);
    return respDataLen;
}

A few curl library stackframes here. These are C code, not C++.

ISTATUS HTTPTransport::invoke()
{
    invokeCleanup();

    //make the HTTP call
    CURLcode retCode;
    try{
    retCode = curl_easy_perform(m_pCurl);
    }
    catch(std::bad_alloc& ba)
    {
        strcpy(m_pErrMsg,ba.what());
        m_status = IFAILURE;
    }
}
void HTTPResponseBuff::grow()
{
如果(m_nmaxize>m_nStartConstGrowSize)
m_nMaxSize+=m_nConstrowSize;
其他的
m_nmaxize=2*m_nmaxize;
char*pTmp=新字符[m_nmaxize];
. . . 
}
void HTTPResponseBuff::write(常量字符*pBuf,大小长度)
{
char*pCh;
同时(获取剩余产能(pCh)写入(pChar,respDataLen);
返回响应;
}
这里有几个框架。这些是C代码,不是C++。
ISTATUS HTTPTransport::invoke()
{
调用ecleanup();
//进行HTTP调用
卷曲编码和重编码;
试一试{
retCode=curl\u easy\u perform(m\u pCurl);
}
捕获(标准:错误分配和ba)
{
strcpy(m_pErrMsg,ba.what());
m_状态=IFAILURE;
}
}

另外,我捕获坏的alloc时的stackframes(在紧靠新语句的catch子句中)在这里:

如果可能的话发布代码,在没有代码的情况下,我已经编写了一个小测试,try/catch似乎可以很好地工作,即使还有几个stackframe(该示例在gcc中也可以正常工作):

void foo()
{
int*myarray=newint[100000000];
}
void foo1()
{
int i=9;
foo();
}
void foo2()
{
int j=9;
foo1();
}
int main(){
尝试
{
foo2();
}
捕获(例外和e)
{

您提到了异常源和try-catch之间的第三方函数。 如果这些第三方函数不是c++(例如具有c链接,比如用c编写的libcurl),那么异常处理将不会像预期的那样工作

在回调通过第三方层传播之前,您需要捕获回调中的所有异常,并使用错误代码(或自定义机制)将信息输入调用方,或者完全放弃使用异常


当你问我做了什么时:我通过一个可用的空指针将调用方的上下文对象注入回调。因此我将上下文对象更改为具有ErrorStatus和ErrorMessage成员,并使用它们通过C层传播错误

struct Context{
    ErrorCode errorCode;
    const char* errorMessage;
    //other stuff
}

void callback(T arg, void* context){
   try{
      new(int);
   }catch(std::exception &e){
       context.errorCode=getErrorCode(e);
       context.errorMessage=e.what();
   }

}

void caller(){
    Context context;
    thirdparty_function(context);

}
如果你不担心线程安全,你也可以使用全局变量


这样说,处理内存错误可能是很棘手的,因为你应该避免为错误消息分配额外的内存< /p>它是什么编程语言?它看起来是C++ + o.c++。它与调用堆栈中的函数没有“抛出的BADOL OLLC”有关吗?中间的STACKFrand是从第三方来的。你可以发布一个代码样本来展示这个行为吗?抛出的规范在C++中并不常用,在C++ 0x中不被推荐。我不会把它们添加到新的代码中。BADYOLLC用于内存不足的情况。可能不允许在抛出和捕获之间分配额外内存。这可能解释了为什么一个紧的try-catch有效,而大的try-catch失败。你可以看一下这张图片,而不是我发布代码,没有人在抛出和捕获之间分配额外内存。这只会如果LIGBRIL的中间帧从catch子句中捕获异常并分配内存,这是高度想象的,是的,中间堆栈帧确实是C,不是C++。如果异常处理不会像预期的那样工作,这会使事情变得复杂,因为问题在回调函数中是已知的,但是我怎么能知道呢?向下传播此信息,并停止程序的进一步执行?请告诉您在项目中做了什么?回调函数只有一个void返回类型。

struct Context{
    ErrorCode errorCode;
    const char* errorMessage;
    //other stuff
}

void callback(T arg, void* context){
   try{
      new(int);
   }catch(std::exception &e){
       context.errorCode=getErrorCode(e);
       context.errorMessage=e.what();
   }

}

void caller(){
    Context context;
    thirdparty_function(context);

}