如果构造函数无法在C ++中分配内存,该怎么办?

时间:2010-07-05 01:50:04

标签: c++ memory constructor return allocation

我刚遇到一个问题,即类的构造函数需要分配内存。所以我很高兴地写了char *mem = static_cast<char*>(malloc(100*sizeof(*mem)));。但后来我突然意识到,如果出现错误,我无法返回错误代码(我的代码中没有使用异常)。我该如何解决这个问题?

我应该添加bool initialized成员,然后在上课后再检查,如下所示:

myClass mc;
if (!mc.initialized) {
    printf("Memory allocation failed in mc's constructor\n");
    exit(1);
}

谢谢,Boda Cydo。

4 个答案:

答案 0 :(得分:9)

你应该使用new,而不是malloc。当你内存不足时,新抛出std :: bad_alloc。如果您未能分配(或由于任何其他原因导致初始化问题),则应从构造函数传播异常,因为这是阻止析构函数被调用的唯一方法。如果构造函数成功完成,则必须调用析构函数(当然,除非它已分配堆并且从未释放)。

答案 1 :(得分:5)

这就是发明的异常。另外,请使用new代替malloc(3)

答案 2 :(得分:3)

如果你没有使用异常,你不应该使用构造函数(或者不应该编写可能失败的构造函数),因为正如你所注意到的,除了通过一个构造函数之外没有办法报告错误例外。您可以交替使用工厂函数并使用它来解除可能失败的位而不能

的位
class myClass {
  private:
  char *m_malloced_buffer;

  // disallow calling ctors/dtors directly
  myClass(char *malloced_buffer) : m_malloced_buffer(malloced_buffer) {}
  ~myClass() { free(m_malloced_buffer); }

  public:
  static myClass *create()
  {
     char *buf = static_cast<char*>(malloc(100*sizeof(*mem)));
     if(!buf) return NULL;

     void *myClassRes = malloc(sizeof(myClass));
     if(!myClassRes) return NULL;
     new (myClassRes) myClass(buf); // placement new, uses existing memory to invoke the ctor
     return static_cast<myClass*>(myClassRes);
  }
  static void destroy(myClass* val)
  {
     if(!val) return;
     val->~myClass(); // explicitly invoke dtor
     free(val); // deallocate memory
  }
};
...
myClass *val = myClass::create();
if(val) { ... }
myClass::destroy(val);

在这个例子中,我使用了malloc并且可以自由地进行所有分配,你可以使用new(std :: nothrow)和删除一样容易。您必须提取每个可能失败的操作并进入工厂函数,以便您可以检查错误而不使用异常。即使在这个简单的例子中,你也可以看到这是一个巨大的痛苦。你说你在评论中得知“异常不是好的编码风格”,你的意思是你学习了(无论是通过有理由的论据和解释的指令,还是来自经验),或者有人说“例外”不是很好的编码风格“你已经接受了这个声明作为教条?

使用bool初始化成员会导致僵尸对象出现问题(请参阅http://www.parashift.com/c++-faq-lite/exceptions.html)。

答案 3 :(得分:2)

如果您使用的是C ++而不是C,那么您应该使用new而不是malloc。抛出异常可能就是你想在构造函数中做的事情。

如果您正在使用new(nothrow)但是因为您不想要异常,或者您正在使用malloc,那么您可以简单地测试为NULL返回的指针。然后,您将设置一个成员变量,指示该对象处于失败状态。这可以在标准C ++库的流类中看到。