C++中调用longjmp时std::runtime_error对象是否会发生内存泄漏?
问题结论:会发生内存泄漏
上述代码执行后,std::runtime_error对象本身、其内部存储的字符串都会发生内存泄漏,具体原因如下:
- C++标准明确规定:使用
longjmp从作用域跳出时,若跳转路径上存在需要调用析构函数的非平凡类型对象,这些对象的析构函数不会被自动调用,属于未定义行为,你给出的代码刚好符合这个场景。 - 异常对象本身的泄漏:当你执行
throw std::runtime_error(message)时,C++运行时会在专门的异常存储区域(通常是堆上动态分配)创建std::runtime_error实例,这个实例的生命周期会持续到异常处理流程完全结束(也就是正常走完catch块之后)才会被运行时自动销毁。你在catch块中直接调用longjmp跳转走,没有完成正常的异常处理流程,运行时不会触发该异常对象的销毁逻辑,所以对象本身占用的内存直接泄漏。 - 内部字符串的泄漏:std::runtime_error内部会持有传入的错误字符串的拷贝,这部分内存绝大多数实现都是动态分配的(哪怕部分实现用了小字符串优化,内存存在对象自身的存储空间里,也会随着异常对象本身未销毁而泄漏)。因为异常对象的析构函数没有被调用,内部字符串的释放逻辑自然也不会执行,这部分内存同样泄漏。
额外说明:你代码try块内定义的
std::string message对象不会泄漏,因为执行throw语句时,首先会把message的内容拷贝到异常对象中,之后离开try块作用域时message会被正常析构。
内容的提问来源于stack exchange,提问作者anymous.asker
相关产品推荐
相关产品推荐

