C ++内存管理技术/实践

时间:2012-05-22 16:03:27

标签: c++ memory-management

我用C ++开始了一个项目。这种语言的内存管理对我来说是新的。

我曾经用new ()创建对象,然后传递指针,当它工作时,调试很痛苦,人们在看到代码时看着我很有趣。我很自豪它没有泄漏或段错(一旦修复),但它确实付出了很多努力。

list <struct Connection *> users;

struct Connection * accept_connection (const char *name) {
  struct Connection * new_node = new Connection ();
  new_node->_data = ... // whatever, set it up here
  return new_node;
}

struct Connection * new_user = accept_connection (const char *name);
users.append (new_user);

所以我为这个项目的下一个版本制定了新策略。到目前为止,我正在做的是使用new ()创建对象并为它们分配唯一的整数ID号。然后,我使用ID作为键将对象存储在散列表中。现在,项目以整数ID号存储和传递,当您需要取消引用它时,您将转到哈希表,它会返回thing *NULL。因此,我不再遇到指针错误,但代码的速度有所降低。

typedef unsigned long ID_Number;

// create a user and return the ID
ID_Number create_user () {
  ID_Number new_id = assign_unique_id ();
  struct User * node = new User ();
  node->_id = new_id;
  node->_data = ... // whatever, set it up here
  add_to_users_dict (new_id, node);
  return new_id;
}

list <ID_Number> users;

for_each (users.begin(), users.end(), process_user);

void process_user (ID_Number i) {
  struct User * u_ptr = lookup_user_dict (i);
  if (u_ptr == NULL) {
    // not found in dict
    // somehow this guy was deleted
  } else {
    // we can do stuff with this guy
  }
}

现在我熟悉编程的基本原则,但作为一个自学成才的爱好者,我不熟悉行业实践和工具。 我基本上要求的是内存管理指南:

1)我在做什么是对还是错?

2)我可以使用哪些软件包或库来帮助我吗?

3)该行业的标准做法是什么?

4)基本上我应该用什么谷歌搜索或购买点燃等?

今天我通常使用Python,它确实为我处理了很多“后端”的东西,但我需要C或C ++(我想我使用普通的C加上stdc ++库,我不太确定出于速度/性能的原因,语言之间的重叠是 - 我只知道g ++编译好了):虽然我怀疑一些数学天才可以提供算法修复,这会加速它的结束,尽管这是一个单独的问题。

4 个答案:

答案 0 :(得分:5)

我能给出的最佳答案是,你不应该以传统的方式使用指针。 C ++ 11改变了程序员处理内存管理的方式。

与其解释已经比我自己更聪明的人详细解释的事情,我只会提供一些链接。

你要看的第一个是Herb Sutter的文章Elements of Modern C++ Style 然后查看Bjarne Stroustrup C++11 Style

的视频

如果你能够使用新的C ++ 11标准,它可以使内存管理比以前更清晰。

答案 1 :(得分:2)

  

我在做什么是对还是错?

您实际上创建了一个使用句柄来引用对象而不是直接指针的系统。这适用于某些情况。 OS&#34;拥有&#34;操作系统通常使用句柄。对象并管理其生命周期,但允许客户端引用它。

  

我可以使用哪些软件包或库来帮助我吗?

现代C ++中的标准库有shared_ptr和unique_ptr,它们是管理动态对象生命周期的智能指针。它们是使用RAII的好方法。

  

该行业的标准做法是什么?

C ++中的事实标准是RAII - 资源分配是初始化。 RAII将分配给构造函数并将解除分配给析构函数。由于C ++可以很好地保证c&tors和d&t执行的方式和时间,因此这为您提供了一种管理对象生命周期而无泄漏的完美方法。智能指针shared_ptr和unique_ptr也使对象的所有权显式化。

  

基本上我应该用什么谷歌搜索或购买点燃等?

搜索RAII。

答案 2 :(得分:1)

  

1)我在做什么是对还是错?

您没有使用资源获取初始化(RAII)习惯用法或现代C ++所有权语义。

  

2)我可以使用哪些软件包或库来帮助我吗?

如果你确实需要传递指针,可以使用std :: unique_ptr和std :: shared_ptr。但在开始之前,您应该了解如何使自己的对象充当RAII语义的资源所有者。

  

3)该行业的标准做法是什么?

     4)基本上我应该用什么谷歌搜索或购买点燃等?

RAII

答案 3 :(得分:1)

您的第一个错误是使用new

很少需要动态内存,它甚至比“直接”需要更少:大多数动态分配的对象都存在于容器中(如vectormap)。

你的第二个错误是不使用构造函数,一旦你理解了什么是类不变量以及构造函数如何启用它们,那么你将能够利用RAII(资源获取是初始化)并停止在C中编码。