【问题标题】:constructor with string and bad_alloc check带有字符串和 bad_alloc 检查的构造函数
【发布时间】:2018-12-03 05:07:39
【问题描述】:

我是一名 C++ 初学者,我正在用 C++ 编写一个课程,我正在使用std::string。 如何处理bad_alloc 异常? 我能做到吗:

Temp::Temp(const string name) :
{
    try {
        name(name);
    }
    catch(std::bad_alloc& a) {
        cout << "bad alloc error" << endl;
    }
}

或者我应该这样做

Temp::Temp(const string name) :
 name(name)
{
    catch(std::bad_alloc& a) {
        cout << "bad alloc error" << endl;
    }
}

我想捕获异常,以便能够防止内存泄漏,然后可能会再次抛出它。
另外,当我从std::string 使用x.assaing(y) 时,我是否也必须检查bad_alloc 异常? (如果我想处理内存泄漏。) 我正在寻找一种没有智能指针的方法(我们还没有学过)。

【问题讨论】:

  • 只是:Temp::Temp(const string name) : name(name) { }
  • 贴出来的代码不会有内存泄漏。
  • 您通常会在main 中捕获bad_alloc,打印一条消息并退出。通过捕获异常来处理内存泄漏,不如通过编写异常安全代码来处理。像Temp::Temp(const string &amp; name) : name(name) {} 这样的简单代码是异常安全的,不需要做任何额外的事情。
  • 我想添加更多字段并在另一个类中创建一个临时数组,所以如果分配失败我想打印一条消息或者抛出一个不同的异常来清除数组(如果可能的话-我不想在其他类中捕获 bad_alloc)
  • @M.ams - 如果您得到bad_alloc,那是因为无法分配内存。所以没什么可泄露的。 :-) 如果您创建一个字符串数组(或vector),中途出现异常将使编译器恢复所有内容,并且那里也没有泄漏。因此,请阅读异常安全保证,不要太努力地手动执行操作。 :-)

标签: c++ string memory-management constructor exception-handling


【解决方案1】:

通过member initializer list 中的构造函数初始化std::string 类型的成员不会导致内存泄漏。

#include <string>
struct Temp
{
   Temp (const std::string& name): name(name) {}
   std::string name;
};

Temp t ("yourname");
std::cout << t.name; // yourname

更新: (由@Deduplicator 建议)

如果只使用一个ctor,不妨使用std::string_view,它是:

char-like 对象的连续连续序列

喜欢:

#include <string_view>
struct Temp
{
   Temp (std::string_view name): name(name) {}
   std::string name;
};

Temp t ("yourname");
std::cout << t.name; // yourname

【讨论】:

  • 如果只有一个演员,那就更好了:Temp(std::string_view name) : name(name) {}
  • 嗯,string_view 总是按值传递,如果你可以选择的话,因为它是一个轻量级视图,而不是一个潜在的重容器。
  • @Deduplicator,我明白了。并且总是const -(指的是一个恒定的连续连续序列的类似字符的对象)?
  • Yes. 同样有趣的是std::span,迄今为止(c++20 之前)仅作为gsl::span 提供。
【解决方案2】:

如果字符串构造确实抛出了 bad_alloc,那么您几乎无法从中恢复。您当然不应该将字符串的每个构造都包装在 try 块中。相反,您应该允许异常冒泡到更高级别,例如您的 main 函数,在那里捕获它,以某种方式报告错误,并可能终止程序。通常,您希望在可以合理处理的最高级别捕获异常。

【讨论】:

  • 嗨,这是一个没有 main 的练习,所以我希望在不提交 main 的情况下捕获异常并处理它(清除所有内存并退出程序)。有没有办法捕获构造函数中的异常?
  • 我认为你误解了这个练习。而且在字符串构造过程中实际上不太可能抛出 bad_alloc。
  • 但是如果我不处理 bad_alloc 将会有内存泄漏。所以我需要捕获异常并处理它,然后再次抛出它,这样当我们退出程序(使用主程序)时,所有内存都会被清除。
  • 不会有内存泄漏。
  • 这不是唯一的类,例如还有另一个类有一个 Temps 数组。所以如果在其中一个 Temp 分配中会有一个 bad_alloc,我需要先清除数组。还是我错了,这里不可能有内存泄漏?
猜你喜欢
  • 2021-02-10
  • 2014-11-21
  • 1970-01-01
  • 2021-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-23
相关资源
最近更新 更多