0

我正在寻找一种方法将大型数据数组(存储在具有基本功能的类中,例如检查数据、大小等)放入任何 STL 容器中,例如向量或队列(FIFO 队列是最好的,因为我有一个生产者和消费者)。

问题是我必须实现复制构造函数并且..好吧..我不想做一个深拷贝(因为它需要太多时间,所以我坚持一个浅拷贝),但是我又一次有了不知道何时删除析构函数中的数据数组的问题(因为我两次调用析构函数并且只有一次数据,另外,对析构函数的第一次调用可能来自在容器中插入/移动元素,所以我此时仍然需要数组数据)。

我考虑过对数据数组使用像 std::shared_ptr 这样的智能指针,但是从我读到的内容来看,它们不调用 delete [] 而是调用 delete - 这是一种耻辱,因为我有一个普通的数组 []。

现在我有一个解决方案,可以在将其从容器中删除之前手动调用类上的“DeleteArray”函数。它工作得很好但是.. 它不是很好。

有任何想法吗?

4

6 回答 6

3

Boost 有一个shared_array类似shared_ptr但会使用的类delete[],或者您可以添加一个自定义删除器以shared_ptr使其调用delete[]

于 2011-01-23T22:48:08.040 回答
1

不要使用数组,std::vector而是使用 a 。然后用智能指针指向它。

于 2011-01-23T22:48:50.690 回答
1

更好shared_ptr的解决方案是将大对象放入容器中,并避免昂贵的副本一起使用。

编辑0:

当然,另一种选择是使对象本身轻量级并且可以使用shared_array. 正如耶利米建议的那样。

于 2011-01-23T22:50:54.747 回答
0

数组有一个shared_ptr等价物,至少在 Boost 库中是这样。它被称为shared_array,它的行为完全符合您的预期。在http://www.boost.org/doc/libs/1_45_0/libs/smart_ptr/shared_array.htm?sess=8940ad57baa307d68cb2e7fd2939d2db查看规范。

于 2011-01-23T22:48:35.027 回答
0

您可以在复制构造函数中实现简单的引用计数。您可以在每次删除时减少引用。

于 2011-01-23T22:54:38.263 回答
0

非常感谢您所有有见地的回答!

这提醒了我为什么上次遇到这个问题时,我没有复制自己就手动编写了一个队列。我不能说我花了比弄清楚如何做漂亮、干净的版本花更多的时间。:)

所以..我所做的是:

解决方案 a) 就像在原始帖子中描述的那样,我创建了一个必须在从向量中删除类之前显式调用的函数。不太好,但效果很好,我不必弄乱其他任何东西,只要记住调用它。

解决方案 b) 我将数组放在另一个类中,并对该类使用了智能指针 (shared_ptr)。工作得非常好。我也必须使用 shared_ptr 作为向量的元素。(一开始我没有想到这一点。)

解决方案 c) 使用 shared_ptr 来保存一个数组。事实证明这是一个非常糟糕的主意,因为它调用 delete 而不是 delete [] 您需要提供您的自定义删除器,并且以某种方式出现了一些其他(语法)问题,因此我花了 2h+ 之类的时间来完成该解决方案。

它在头文件中看起来像这样:

 template< typename T >
  struct
array_deleter
  {
      void
    operator ()( T const * p)
      { delete[] p; }
  };

class MemoryStressChunk
{
private:
    int chunkSizeInValues;
    std::shared_ptr< __int64 > data;
};

并在代码文件中:

data.reset(
    new __int64[chunkSizeInValues], 
    array_deleter< __int64 >() );

要使用它,我必须再次将其取出:

__int64 *d = data.get();

下次我可能会强烈考虑使用 boost 版本。我的机器上没有提升,所以这就是为什么它不是我的选择。

我认为解决方案 d) 是使用包含 shared_ptr 的类向量到向量(而不是数组)。毕竟我和 c) 玩得很开心,但我并没有这样做。:)

如果有人想看一下代码,你可以在这里得到它http://andreas-reiff.de/wp-content/uploads/2011/01/Tool-MemTester.zip。请注意版本 a) 中可能存在 memleak(使用 shared_ptr 作为版本 b) 中的类)。

感谢您再次提供帮助!

于 2011-01-24T14:25:18.790 回答