一个原始指针作为参数的shared_ptr

5

当函数需要一个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]); 但是函数原型 read(char* s, streamsize n) 不接受智能指针作为输入?有什么技巧吗?

编辑:我正在尝试编写类似于以下内容的代码:

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

但是它无法编译。


可能是getting a normal ptr from shared_ptr?的重复问题。 - D.Shawley
1
你的问题中已经包含了答案的一部分 - 普通指针没有 get() 方法,但是智能指针有,并且它正好可以做到你所要求的。 - Mark Ransom
一个 shared_ptr 不足以智能地管理数组。然而,如果你给它一个自定义的删除器,一个 unique_ptr 就可以做到。 - Pete Becker
3个回答

6

不必使用指针,可以使用向量代替。

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

vector<char>技巧很好...因此,当API需要原始指针时,没有办法传递智能指针吗? - digit plumber

5

重要警告: 创建一个指向数组的std::shared_ptr<char>会引发未定义行为,因为智能指针将使用delete而不是delete[]来删除指针。请改用std::shared_ptr<char[]>

保留此内容是因为它可能作为一个有用的警告。下面是原始答案...

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

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

使用&*readInBuffer可以达到相同的效果。

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


如果没有自定义删除器,unique_ptr 将仅对存储的指针调用 delete p。由于内存是使用数组 new 分配的,这会产生未定义的行为。 - Pete Becker
哎呀,是的,你说得对。我会把这个留在这里,并添加一个大而明显的警告。 - Thomas
哎呀,糟糕了。我的评论本来是想谈论shared_ptr,结果却说到了unique_ptrshared_ptr根本不处理数组;也没有自定义删除器供shared_ptr使用。不过,在这里可以使用unique_ptr - Pete Becker

1
不,你不能传递一个shared_ptr。但是你可以创建一个,并调用它的get()成员函数来获取原始指针的副本以传递给函数。然而,shared_ptr不处理数组;这就是vector的作用。但是你可以使用unique_ptr来管理数组对象:
std::unique_ptr<char[], std::default_delete<char[]> ptr(new char[whatever]);
f(ptr.get());

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接