【问题标题】:shared_ptr with malloc and free带 malloc 和 free 的 shared_ptr
【发布时间】:2012-08-29 04:26:23
【问题描述】:

我在包含 c 和 cpp 的大型应用程序中工作。所有文件都保存为 cpp 扩展名,但代码是用 c-style 编写的。我的意思是它是通过 malloc 和 realloc 和 calloc 定义结构而不是类分配内存。最近他们已经安装了 boost 库所以我打算在我现有的代码库中使用所以我有一些以下问题。

  1. 我可以将 std::shared_ptr 与 malloc 和 free 一起使用吗?
  2. 如果是,谁能指出我的示例代码库?
  3. 如果我在我的应用程序中创建 std::shared_ptr 并将此指针传递给另一个使用 malloc 或 calloc 的函数,它会影响任何功能吗?

或者换句话说:

对于以下代码,如何使用 std::shared_ptr 实现类似的功能:

void allocateBlocks(int **ptr, int *cnt)
{
    *ptr = (int*)malloc(sizeof(int) * 10);
    *cnt = 10;
    /*do something*/ 
}

int main()
{
    int *p = NULL;
    int count = 0;
    allocateBlocks(&p, &count);
    /*do something*/

    free(p);
}

我们调用一些函数,它们接受双指针并填充其应用程序内部的结构并使用 malloc。我们可以将这些指针分配给 std::shared_ptr 吗?例如:

typedef struct txn_s
{
    int s;
    int d;
    int *e;
} txn_t;

typedef boost::shared_ptr<txn_t> tpointer;

tpointer((txn_t*)::malloc(sizeof(txn_t),::free));

【问题讨论】:

  • 是的,shared_ptr&lt;T&gt; sp((T*)::malloc(...), ::free),取决于他们如何使用指针,是的 (T* p; fill_p(&amp;p); shared_ptr&lt;T&gt; sp(p, ::free);)。不过,我建议使用允许删除器的手写scoped_ptr(类似于std::unique_ptr 允许删除器作为模板参数的方式)。
  • 对不起,我不太清楚你的例子。你的意思是当我分配内存时,我们将调用免费。对于Exp
  • shared_ptr 的第二个参数是删除器,也就是应该释放指针时调用的东西。

标签: c++ boost shared-ptr scoped-ptr


【解决方案1】:

我可以将 shared_ptr 与 malloc 和 free 一起使用吗?

是的。

谁能指出我的示例代码库。

您需要提供自定义删除器,以便使用free 而不是默认的delete 释放内存。这可以是指向free 函数本身的指针:

shared_ptr<void> memory(malloc(1024), free);

请记住,mallocfree 仅处理原始内存,您有责任正确创建和销毁您可能希望保留在该内存中的任何重要对象。

如果我在我的应用程序中创建 shared_ptr 并将这个指针传递给另一个函数(如果他们使用 malloc 或 calloc)。它会影响任何功能吗?

我不太明白这个问题。如果您要问的话,您可以将此shared_ptr 与“普通”共享指针互换使用。 类型擦除 确保指针的用户不受不同类型的删除器的影响。与任何共享指针一样,如果使用get() 提取原始指针,则必须小心;具体来说,不要做任何可能free 它的事情,因为您已经不可撤销地将所有权分配给共享指针。

我们调用了一些函数,它接受双指针并填充其应用程序内部的结构并使用 malloc 我们可以将这些指针分配给 shared_ptr。

我猜你的意思是这样的:

double * make_stuff() {
   double * stuff = static_cast<double*>(malloc(whatever));
   put_stuff_in(stuff);
   return stuff;
}

shared_ptr<double> shared_stuff(make_stuff(), free);

更新:我没有发现短语“双指针”,我假设您的意思是 C 风格使用指针来模拟引用以模拟返回值;你也可以这样做:

void make_stuff(double ** stuff);

double * stuff = 0;
make_stuff(&stuff);
shared_ptr<double> shared_stuff(stuff, free);

如何处理 realloc 和 calloc

可以使用calloc 的结果初始化共享指针,或者使用free 返回要释放的内存的任何其他内容。您不能使用realloc,因为shared_ptr 已经取得了原始指针的所有权,并且不会在不调用free 的情况下释放它。

【讨论】:

  • 我认为“双指针”可能意味着 void allocate(int** p) 会将 *p 分配给新内存。我认为这很难使用共享指针。
  • @RasmusStorjohann:这并不比任何其他获取指针的方式更难。我已经更新了答案,以防万一。
【解决方案2】:

要将std::shared_pointermalloc()free() 一起使用,您应该指定一个自定义删除器。应该这样做

std::shared_ptr<T> ptr(static_cast<T*>(malloc(sizeof(T))), free);

只要你不传递std::shared_ptr&lt;T&gt;::get()的结果,你的指针就是安全的。

编辑:添加了将malloc() 的结果转换为T*

【讨论】:

  • 需要演员,不需要ptr_fun(不管是什么),为什么.get()不安全(好吧,除非传递给frees它)?
  • @Xeo:感谢演员。由于我不知道 OP 的代码并且当他将其传递给 C 时,存在潜在问题,即某些代码在 .get() 的值上调用 free(),这会破坏 shared_ptr
【解决方案3】:

我可以将 shared_ptr 与 malloc 和 free 一起使用吗? 如果是,谁能指出我的示例代码库。

是的。 shared_ptr 本身不分配内存。但是,一旦引用计数降至零,它就会删除您的对象。由于它默认使用delete,并且您不能将它与malloc(或任何其他方式)分配的对象一起使用,因此您必须使用custom deleter

如果我在我的应用程序中创建 shared_ptr 并将这个指针传递给另一个函数(如果他们使用 malloc 或 calloc)。它会影响任何功能吗?

不清楚你在这里问什么。如果该函数不希望传递共享指针,则必须格外小心。但这取决于该函数的实际作用。

我们调用了一些函数,它接受双指针并填充其应用程序内部的结构并使用 malloc 我们可以将这些指针分配给 shared_ptr。

是的,您可以将任何指针与shared_ptr 一起使用。

【讨论】:

    猜你喜欢
    • 2012-06-10
    • 1970-01-01
    • 2021-12-11
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    相关资源
    最近更新 更多