首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有人能解释一下如果在堆上分配对象数组的过程中抛出异常会发生什么吗?

有人能解释一下如果在堆上分配对象数组的过程中抛出异常会发生什么吗?
EN

Stack Overflow用户
提问于 2011-11-17 21:51:58
回答 2查看 1.3K关注 0票数 3

我定义了一个类foo,如下所示:

代码语言:javascript
复制
class foo {
private:
   static int objcnt;
public:
   foo() {
       if(objcnt==8)
           throw outOfMemory("No more space!");
       else
          objcnt++;
   }

   class outOfMemory {
   public:
       outOfMemory(char* msg) { cout << msg << endl;}
   };

   ~foo() { cout << "Deleting foo." << endl; objcnt--;}
};
int foo::objcnt = 0;

下面是主要函数:

代码语言:javascript
复制
int main() {
    try {
            foo* p = new foo[3];
            cout << "p in try " << p << endl;
            foo* q = new foo[7];
        }catch(foo::outOfMemory& o) {
           cout << "Out-of-memory Exception Caught." << endl;
        }
}

很明显,"foo* q= new foo7;“这一行只成功创建了5个对象,并且在第6个对象上抛出了内存不足异常。但事实证明,只有5次析构函数调用,并且没有为存储在p指向的位置的3个对象的数组调用析构函数。所以我想知道为什么?为什么程序只调用这5个对象的析构函数?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-17 21:57:42

析构函数只为完全构造的对象调用-这些对象的构造函数正常完成。只有在new[]执行过程中抛出异常时,这种情况才会自动发生。因此,在您的示例中,将为在q = new foo[7]运行期间完全构造的五个对象运行析构函数。

由于p所指向的数组的new[]已成功完成,因此该数组现在被处理到您的代码中,并且C++运行时不再关心它-除非您执行delete[] p,否则不会运行析构函数。

票数 6
EN

Stack Overflow用户

发布于 2011-11-17 23:41:38

当您在堆上声明数组时,您将获得预期的行为:

代码语言:javascript
复制
int main()
{
    try
    {
        foo   p[3];
        cout << "p in try " << p << endl;
        foo   q[7];
    }
    catch(foo::outOfMemory& o)
    {
       cout << "Out-of-memory Exception Caught." << endl;
    }
}

在您的代码中,只有指针是局部自动变量。当堆栈展开时,指针没有任何相关的清理。正如其他人所指出的,这就是为什么在C++代码中通常没有原始指针的原因,它们通常被包装在一个类对象中,该类对象使用构造函数/析构函数来控制它们的生命周期(智能指针/容器)。

顺便说一句。使用std::vector通常比使用原始数组更好(在C++11中,如果您有固定大小的数组,std::array也很有用)。这是因为堆栈的大小有限,而这些对象将大部分数据放在堆中。这些类对象提供的额外方法使它们更易于在其余代码中处理,如果您一定要将旧式数组指针传递给C函数,则很容易获得这些方法。

代码语言:javascript
复制
int main()
{
    try
    {
        std::vector<foo>     p(3);
        cout << "p in try " << p << endl;
        std::vector<foo>     q(7);

        // Now you can pass p/q to function much easier.

    }
    catch(foo::outOfMemory& o)
    {
       cout << "Out-of-memory Exception Caught." << endl;
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8168203

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档