我有一个库函数,它需要四个指针数组作为参数:f(unsigned char* data[4])
,而我的代码std::unique_ptr<unsigned char> myArray[4]
中也有一个智能指针数组。
是否可以通过此库函数使用智能指针?
我已经尝试过了,但这给了我一个段错误:f(reinterpret_cast<unsigned char **>(myArray[0].get()));
答案 0 :(得分:6)
std::array<unsigned char* , 4> arr = { myArray[0].get(),myArray[1].get(),myArray[2].get(),myArray[3].get() };
通过arr.data()
。
答案 1 :(得分:2)
您的演员选错了。您正在转换存储在第一个数组元素中的unsigned char *
指针。您将需要强制转换元素本身的地址:
f(reinterpret_cast<unsigned char **>(&myArray[0]));
或者甚至强制转换数组本身:
using puchar = unsigned char *;
f(reinterpret_cast<puchar(&)[4]>(myArray));
但是,这些方法之所以起作用,是因为std::unique_ptr
被设计为没有比原始指针更多的存储开销。但是使用这些解决方案是不确定的行为。正确的解决方案是简单地将指针复制到另一个数组,例如:
unsigned char* myArrayOfPtrs[] = { myArray[0].get(), myArray[1].get(), myArray[2].get(), myArray[3].get() };
f(myArrayOfPtrs);
或者:
unsigned char* myArrayOfPtrs[4];
for (int i = 0; i < 4; ++i) {
myArrayOfPtrs[i] = myArray[i].get();
}
f(myArrayOfPtrs);
或者:
#include <algorithm>
unsigned char* myArrayOfPtrs[4];
std::transform(std::begin(myArray), std::end(myArray), std::begin(myArrayOfPtrs),
[](auto &p) { return p.get(); }
);
f(myArrayOfPtrs);
答案 2 :(得分:0)
如果您确定自己的class Program
{
internal class ParsedObject
{
public string Name;
public string Store;
}
static void Main(string[] args)
{
string json = @"
{
""2"":
{
""name"": ""Cannonball"",
""store"": 5
},
""6"":
{
""name"": ""Cannon base"",
""store"": 187500
},
""8"":
{
""name"": ""Cannon stand"",
""store"": 187500
}
}";
var jsonDeserialized = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, ParsedObject>>(json);
Console.WriteLine(jsonDeserialized["2"].Name);
}
}
不会超出范围,并希望它保留关联指针的所有权,则可以对数组中的每个指针使用unique_ptr
并创建一个常规数组指针。
char* a[] = {myArray[0].get(), myArray[1].get(), myArray[2].get(), myArray[3].get()}
保留对unique_pointers
资源的所有权,如果它们超出范围,则char*
析构函数将释放指针。
如果您要释放所有权,则可以在unique_ptr
上使用release()
方法,这将使您可以安全地转换为常规指针,并确保unique_ptr
出局作用域不会取消分配底层char *资源。
unique_ptr
:https://en.cppreference.com/w/cpp/memory/unique_ptr/release
release()
:https://en.cppreference.com/w/cpp/memory/unique_ptr/get