【问题标题】:shared_ptr for a raw pointer argumentshared_ptr 用于原始指针参数
【发布时间】:2012-11-15 19:55:56
【问题描述】:

当函数需要char*时,可以传入shared_ptr吗?

我正在读取整个文本文件(长度 = 100),并希望将 char 存储到 char[] 数组中。我使用的幼稚方式是这样的:

ifstream dictFile(fileName);
size_t fileLength = 100;
char* readInBuffer(new char[fileLength]);
dictFile.read(readInBuffer, fileLength);
//processing readInBuffuer..............
delete[] readInBuffer;
dictFile.close();

当然,如果在 delete[] 语句之前抛出异常,则存在内存泄漏。我想知道我是否可以使用 shared_ptr readInBuffer(new char[fileLength]); 但是函数原型

读取 (char* s, 流大小 n)

不接受智能指针作为输入?有什么技巧吗?

编辑:我正在尝试写这样的东西:

shared_ptr<char[]> readInBuffer(new char[fileLength]);
dictFile.read(readInBuffer.get(), fileLength);

但它不会编译。

【问题讨论】:

  • 您的问题中已经有了部分答案 - 常规指针没有 get() 方法,但智能指针有,而且它完全符合您的要求。跨度>
  • shared_ptr 不够聪明,无法管理阵列。但是,unique_ptr 是,如果你给它一个自定义删除器。

标签: c++ function pointers smart-pointers


【解决方案1】:

您可以使用向量代替指针,而不是使用指针。

std::vector<char> readInBuffer(fileLength);
dictFile.read(&readInBuffer[0], fileLength);

【讨论】:

  • vector 技巧很好...所以,当 API 需要原始指针时,就没有办法传入智能 ptr 了吗?
【解决方案2】:

BIG FAT 警告:创建指向数组的std::shared_ptr&lt;char&gt; 会引发未定义的行为,因为智能指针将delete 指针,而不是delete[] 它。请改用std::shared_ptr&lt;char[]&gt;

将其留在这里,因为它可能是一个有用的警告。原始答案如下...

get() 函数返回底层原始指针。你已经在你的代码中写了这个!

shared_ptr<char[]> readInBuffer(new char[fileLength]);
dictFile.read(readInBuffer.get(), fileLength);

&amp;*readInBuffer 可以达到相同的结果。

当然,你必须确定dictFile.read() 不是delete 指针,否则恶魔可能会从你的鼻子里飞出来。

【讨论】:

  • 如果没有自定义删除器,unique_ptr 将简单地在存储的指针上调用delete p。由于内存是用数组 new 分配的,这会产生未定义的行为。
  • 哎呀,是的,你是对的。我将把它留在这里并添加一个大警告。
  • 哎呀,回来了。 &lt;g&gt; 当我的意思是 shared_ptr 时,我的评论最终谈到了 unique_ptrshared_ptr 根本不处理数组; shared_ptr 没有自定义删除器。不过,unique_ptr 可以在这里使用。
【解决方案3】:

不,您不能传递shared_ptr。但是您可以创建一个,并调用它的get() 成员函数来获取原始指针的副本以传递给该函数。但是,shared_ptr 不处理数组。这就是vector 的用途。但是您可以使用 unique_ptr 到一个数组来管理该对象:

std::unique_ptr<char[], std::default_delete<char[]> ptr(new char[whatever]);
f(ptr.get());

可能有更短的方法来写第一行,但我没有时间去挖掘它。

【讨论】:

    猜你喜欢
    • 2017-11-03
    • 2021-11-15
    • 2012-09-07
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    相关资源
    最近更新 更多