12

我已经用 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)基本上我应该在谷歌上搜索或购买kindle等什么?

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

4

4 回答 4

9

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

我将提供一些链接,而不是解释比我聪明得多的人已经详细解释过的事情。

首先你应该看看 Herb Sutter 的文章Elements of Modern C++ Style 然后看看 Bjarne Stroustrup C++11 Style的视频

如果您能够使用新的 C++11 标准,那么它使内存管理比以前更干净。

于 2012-05-22T16:16:08.790 回答
2

我在做什么是对还是错?

您实际上创建了一个使用句柄而不是直接指针来引用对象的系统。这可能适用于某些场景。当操作系统“拥有”对象并管理其生命周期但允许客户端引用它时,操作系统通常使用句柄。

我可以使用任何可以帮助我的软件包或库吗?

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

行业的标准做法是什么?

C++ 中的事实标准是 RAII——资源分配是初始化。RAII 将分配与构造函数联系起来,将分配与析构函数联系起来。由于 C++ 对 c'tors 和 d'tors 的执行方式和时间有可靠的保证,这为您提供了一种完美的方法来管理对象生命周期而不会泄漏。智能指针 shared_ptr 和 unique_ptr 也明确了对象的所有权。

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

搜索 RAII。

于 2012-05-22T16:17:52.643 回答
2

您的第一个错误是使用new.

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

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

于 2012-05-22T16:19:14.737 回答
1

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

您没有使用 Resource Acquisition Is Initialization (RAII) 习惯用法或现代 C++ 所有权语义。

2)我可以使用任何可以帮助我的包或库吗?

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

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

4)基本上我应该在谷歌上搜索或购买kindle等什么?

RAII

于 2012-05-22T16:17:27.743 回答