相关疑难解决方法(0)

谁删除了在构造函数中有异常的"新"操作期间分配的内存?

我真的不敢相信我找不到明确的答案......

在使用new运算符初始化C++类构造函数抛出异常后,如何释放分配的内存.例如:

class Blah
{
public:
  Blah()
  {
    throw "oops";
  }
};

void main()
{
  Blah* b = NULL;
  try
  {
    b = new Blah();
  }
  catch (...)
  {
    // What now?
  }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试这个时,b在catch块中是NULL(这是有道理的).

在调试时,我注意到conrol在它到达构造函数之前进入了内存分配例程.

这在MSDN网站上似乎证实了这一点:

当new用于为C++类对象分配内存时,在分配内存后调用对象的构造函数.

因此,请记住,b永远不会分配局部变量(即在catch块中为NULL),如何删除分配的内存?

得到一个跨平台的答案也很好.即,C++规范说什么?

澄清:我不是在讨论类在c'tor中分配内存然后抛出的情况.我很欣赏在这种情况下,不会召唤人.我在谈论用于分配THE对象的内存(Blah在我的例子中).

c++ constructor memory-leaks exception

49
推荐指数
4
解决办法
1万
查看次数

HTML解析类的构造函数应该做多少工作?

对象构造函数做多少工作是合理的?它应该只是初始化字段而不是实际对数据执行任何操作,还是可以让它执行某些分析?

背景: 我正在编写一个类,负责解析HTML页面并根据解析的信息返回各种信息.类的设计使得类的构造函数执行解析,如果发生错误则抛出异常.初始化实例后,解析后的值无需通过访问器进行进一步处理即可使用.就像是:

public class Parser {

    public Parser(final String html) throws ParsingException {
        /* Parsing logic that sets private fields */
        /* that throws an error if something is erroneous.*/
    }

    public int getNumOfWhatevers() { return private field; }
    public String getOtherValue()  { return other private field; }
}
Run Code Online (Sandbox Code Playgroud)

在设计课程后,我开始怀疑这是否是正确的OO练习.解析代码是否应放在void parseHtml()方法中,并且一旦调用此方法,访问者只返回有效值?我觉得好像我的实现是正确的,但我不禁觉得有些OO纯粹主义者可能因为某种原因发现它不正确,并且以下的实现会更好:

public class Parser {

    public Parser(final String html) {
        /* Remember html for later parsing. */
    }

    public void parseHtml() throws ParsingException { 
        /* Parsing logic …
Run Code Online (Sandbox Code Playgroud)

language-agnostic oop constructor

33
推荐指数
4
解决办法
3372
查看次数

为什么在构造函数调用异常后没有释放unique_ptr?

在以下代码中:

#include <memory>
#include <iostream>

void mydeallocator(int * x) {
    std::cerr << "Freeing memory" << std::endl;
    delete x;
}

struct Foo {
    std::unique_ptr <int,std::function <void(int*)>> x;
    Foo(bool fail) : x(new int(1),mydeallocator) {
        if(fail)
            throw std::runtime_error("We fail here");
    }
};

int main() {
    {auto foo1 = Foo(false);}
    {auto foo2 = Foo(true);}
}
Run Code Online (Sandbox Code Playgroud)

看来,Foo(true)调用时内存没有被正确释放.也就是说,当我们编译并运行该程序时,我们得到了结果:

Freeing memory
terminate called after throwing an instance of 'std::runtime_error'
  what():  We fail here
Aborted
Run Code Online (Sandbox Code Playgroud)

我相信该消息Freeing memory应该被调用两次.基本上,根据这个问题这里这里的ISO C++人员,我的理解是堆栈应该在构造函数上展开, …

c++ c++11 c++14

20
推荐指数
1
解决办法
1118
查看次数

std :: make_unique <T> vs reset(新T)

我想问一个关于构造函数中的内存泄漏的问题.我们来考虑一个课程:

 class Foo
 {
   public:
      Foo(){ throw 500;} 
 };
Run Code Online (Sandbox Code Playgroud)

有什么区别

std::unique_ptr<Foo> l_ptr = std::make_unique<Foo>();
Run Code Online (Sandbox Code Playgroud)

std::unique_ptr<Foo> l_ptr;
l_ptr.reset(new Foo());
Run Code Online (Sandbox Code Playgroud)

在我看来,make_unique的解决方案应该保护我免受内存泄漏,但在这两种情况下我得到了相同的valgrind结果:

$ valgrind --leak-check=full ./a.out
==17611== Memcheck, a memory error detector
==17611== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==17611== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==17611== Command: ./a.out
==17611== 
terminate called after throwing an instance of 'int'
==17611== 
==17611== Process terminating with default action of signal 6 (SIGABRT)
==17611==    at 0x5407418: raise …
Run Code Online (Sandbox Code Playgroud)

c++ memory-leaks smart-pointers unique-ptr c++11

10
推荐指数
1
解决办法
2894
查看次数

如果在构造函数中抛出异常,是否会自动删除为对象分配的内存?

假设有这样的代码:

class CFoo
{
public:
    CFoo()
    {
        iBar = new CBar();
    }
private:
    CBar* iBar;
};

....
CFoo* foo = new CFoo();
Run Code Online (Sandbox Code Playgroud)

执行上面的行时,将分配第一个内存来保存CFoo对象.但是如果新的CBar()行引发异常(由于内存不足),系统会自动解除分配先前分配给CFoo对象的内存吗?我认为它必须,但找不到任何明确的参考说明.如果没有,编码器将如何释放内存,因为它不会被分配给foo?

c++

4
推荐指数
1
解决办法
887
查看次数

C++:如果构造函数可能抛出异常,则处理资源(参考FAQ 17.4)

感谢所有的回复.

我重新格式化了我的问题,以便在包含类的构造函数抛出异常之后理解成员指针的状态

我的示例类:)

class Foo
{
public:
    Foo()
    {
       int error = 0;
        p = new Fred;

        throw error;  // Force throw , trying to understand what will happen to p
    }

   ~Foo()
    {
       if (p)
       {
           delete p;
           p = 0;
       }
     }
private:
   Fred* p;
};

int main()
{
      try
      {
         Foo* lptr = new Foo;
      }
      catch (...)
      {}
}
Run Code Online (Sandbox Code Playgroud)

类foo的consturctor会因某些随机原因而抛出异常.我知道foo的desturctor永远不会被调用,但在这种情况下,p的析构函数会被调用吗?

将p作为增强智能指针而不是指向fred的原始指针有什么不同.

谢谢.

c++ exception

1
推荐指数
1
解决办法
7437
查看次数