C++ 将unique_ptr强制转换为char**以将其作为函数参数Func(char**arg)传递
使用c样式C++ 将unique_ptr强制转换为char**以将其作为函数参数Func(char**arg)传递,c++,unique-ptr,C++,Unique Ptr,使用c样式char我会: void FunctionCannotBeChanged(char** pVar) { ... do something/modify the content of the buffer } int main(..) { char* buffer = NULL; Func(&buffer) } 如果我想要一个缓冲区作为唯一\u ptr std::unique_ptr<char[]> buffer; buffer = std
char
我会:
void FunctionCannotBeChanged(char** pVar)
{
... do something/modify the content of the buffer
}
int main(..)
{
char* buffer = NULL;
Func(&buffer)
}
如果我想要一个缓冲区作为唯一\u ptr
std::unique_ptr<char[]> buffer;
buffer = std::make_unique<char[]>(bufferSize);
std::唯一的ptr缓冲区;
buffer=std::使_唯一(bufferSize);
将新缓冲区传递给
函数的正确方法是什么?不能通过引用更改。首先,显示的函数要求缓冲区的类型为char*
,但您的缓冲区的类型为unsigned char*
,类型必须匹配
该函数用于重新分配缓冲区
如果它重新分配了缓冲区,那么一旦您将其传递给函数,它就拥有该缓冲区,因此您的unique\u ptr
不能再拥有该缓冲区,因此您需要重新分配它
这是一个图书馆,对我来说是一个黑匣子
因为库是C库,不可能(除了它是一个C++接口的C++库),重新分配内存的函数与函数<代码> > MaMax唯一> <代码>用作默认分配内存。
库必须记录分配/释放内存必须使用的函数,您必须使用这些函数来创建属于
unuqie_ptr
的缓冲区,并且unqiue_ptr
需要使用正确的函数(例如使用自定义删除器)来释放该缓冲区
如果不相应地这样做,应用程序将遇到未定义的行为
只有在已知您使用的库以及函数的情况下,才能说明如何正确地执行此操作。或者,如果您提供了有关该函数如何重新分配内存的所有必要信息,以及根据库必须使用哪些函数进行内存分配
假设库不进行内存管理,一种可能的方法是为该库创建包装器:
库代码:
void FunctionCannotBeChanged(char** pVar);
// allocator/free functions either provided by the library or documented by the library that those are used
char * LibraryAlloc(size_t size);
void LibraryFree(char * ptr);
您的包装:
namespace lib_wrapper {
// deleter that is used to free the memory using the correct free function
void library_deleter(char * ptr) {
// you might need to add a check if the pointer is a null pointer
LibraryFree(ptr);
}
// define an own unique ptr type that uses that custom deleter
using unique_ptr = std::unique_ptr<char,decltype(&library_deleter)>;
// define an own make_unqiue function that uses the correct allocator
unique_ptr make_unique(size_t size) {
return unique_ptr(LibraryAlloc(size),&library_deleter);
}
// create a wrapper function that:
// - releases the pointer
// - passes it to the library function
// - and then passes the possibly changed ptr back to your unique ptr
void FunctionCannotBeChanged(unique_ptr &ptr) {
auto raw_ptr = ptr.release();
::FunctionCannotBeChanged(&raw_ptr);
ptr.reset(raw_ptr);
}
}
int main()
{
auto buffer = lib_wrapper::make_unique(50);
lib_wrapper::FunctionCannotBeChanged(buffer);
return 0;
}
这取决于你
创建包装在开始时可能需要做很多工作,但会使代码更易于维护,并将陷阱转移到包装代码中的一个中心点,远离使用库的代码部分。没有。您的函数可能会执行与std::unique\u ptr
不兼容的操作。您需要了解哪些功能不能更改
是允许执行的。它究竟如何修改*pvar
?双指针使它变得非常困难。这表明函数可以重新分配数据并重新分配原始指针。这将不可能与智能指针。如果另一个对象中有数据,则需要将数据复制到新的(临时)缓冲区中,传递指向该(临时)缓冲区指针的指针,然后将数据复制回或创建新的智能指针或其他类似字符串的对象(我真的建议您对任何类似字符串的数据使用std::string
,或者可能使用std::vector
,而不是智能指针)。真正的信息是:避免函数(char**)
和使用它的库(如果可以的话)。仍然要考虑所有的事情,如果需要的话,按照前面的评论中的描述去做。另外,比起std::unique\u ptr
@branero79库文档告诉你内存是如何重新分配的吗?@branero79如果库分配内存,如何释放?是否有其他函数?感谢您的详细解释。这些问题是由于我缺乏知识以及我必须使用的库API混乱造成的。
int main()
{
auto buffer = lib_wrapper::make_unique(50);
buffer = lib_wrapper::FunctionCannotBeChanged(std::move(buffer));
return 0;
}