包装总库的最佳实践内存管理
Best practice memory management for wrapping gross library
ooqp
库已在我的工作场所投入使用。现在有个学生正在总结,我在想怎么处理这个问题。下面是程序使用的函数示例:
newQpGenSparse( double ** c, int nx,
int ** irowQ, int nnzQ, int ** jcolQ, double ** dQ,
double ** xlow, char ** ixlow,
double ** xupp, char ** ixupp,
int ** irowA, int nnzA, int ** jcolA, double ** dA,
double ** b, int my,
int ** irowC, int nnzC, int ** jcolC, double ** dC,
double ** clow, int mz, char ** iclow,
double ** cupp, char ** icupp,
int * ierr );
http://pages.cs.wisc.edu/swright/ooqp ooqp-userguide.pdf
总对吧?该库是用c++
编写的,所以我正在寻找一种巧妙地管理内存的方法。
std::shared_ptr
,然后将原始内存暴露给这些函数。这有一个明显的缺点,即shared_ptr
的使用将被违反,特别是当内存被ooqp
函数删除或编辑时。
除了非常小心地使用new和delete之外,有没有更好的方法来处理这个问题?
哎呀!显而易见的答案是将库重构为,而不是像那样做。如果这是不可能的,您可以设计一个类来存储所有的参数类型(希望有更具描述性的名称!)。
class QPGenSparseWrapper
{
// Only store params if you want to manage their memory.
double* Param1;
public:
QPGenSparseWrapper(const double* param1, const int param2 /* , ... */, param16 = 22) :
Param1(param1),
{
newQpGenSparse(&Param1, param2 /* , ... */, param16);
}
virtual ~QPGenSparseWrapper()
{
freeQpGenSparse(/* params */);
// If no corresponding free, use smart pointers or manual delete.
}
void Run(/* more params?!? */)
{
// I hope you know what goes here.
}
};
毫无疑问,您应该为尽可能多的这些参数提供相同的默认值,以便为将来的用户避免这样的麻烦。
据我所知,库函数使用指针而不是引用。我不知道你有多少类似的函数,但如果有很多,那么这个想法可能会为你节省很多编码。
这样你可以使用std::shared_ptr
而忘记freeQpGenSparse
函数。
template<class T>
struct arg_type_to_wrapper_arg_type { typedef T result; };
template<class T>
struct arg_type_to_wrapper_arg_type<T*> { typedef T& result; };
template<class T>
struct arg_type_to_wrapper_arg_type<T**> { typedef std::shared_ptr<T>& result; }; // or unique_ptr
template<class T>
struct arg_value_setter_base {
arg_type_to_wrapper_arg_type<T>& m_value;
T m_new_value;
T& get() { return m_new_value; }
};
template<class T>
struct arg_value_setter : public arg_value_setter_base<T> {
arg_value_setter(arg_type_to_wrapper_arg_type<T>& value) : m_value(value), m_new_value(value) {}
~arg_value_setter() { }
};
template<class T>
struct arg_value_setter<T*> : public arg_value_setter_base<T*> {
arg_value_setter(arg_type_to_wrapper_arg_type<T>& value) : m_value(value), m_new_value(null_ptr) {}
~arg_value_setter() { m_value = *m_new_value; }
};
template<class T>
struct arg_value_setter<T**> : public arg_value_setter_base<T**> {
arg_value_setter(arg_type_to_wrapper_arg_type<T>& value) : m_value(value), m_new_value(null_ptr) {}
~arg_value_setter() { m_value.reset(*m_new_value); }
};
#define CREATE_WRAPPER_FOR_OOQP_ALLOC_FUNCTION(ret_type, function_name, arg_sequence)
/* use boost preprocessor macros to get the following result. You just have to use BOOST_PP_SEQ_FOR_EACH_I 3 times. I will leave this job for you. */
void newQpGenSparseWrapper(
arg_type_to_wrapper_arg_type<double **>::result arg_0, // std::shared_ptr<double>& arg_0
arg_type_to_wrapper_arg_type<int>::result arg_1,
arg_type_to_wrapper_arg_type<int **>::result arg_2, // std::shared_ptr<int>& arg_2
.....,
arg_type_to_wrapper_arg_type<int *>::result arg_x // int& arg_x
)
{
arg_value_setter<double **> arg_setter_0(arg_0);
arg_value_setter<int> arg_setter_1(arg_1);
arg_value_setter<int **> arg_setter_2(arg_2);
.....,
arg_value_setter<int *> arg_setter_x(arg_x);
// TODO: you may want to avoid the assignment in case of the failure of the function to prevent shared_ptr from getting an invalid pointer
return newQpGenSparse(arg_setter_0.get(), arg_setter_1.get(), arg_setter_2.get(), .... , arg_setter_x.get());
}
现在你只需要为你想要换行的每个函数写一行代码:
CREATE_WRAPPER_FOR_OOQP_ALLOC_FUNCTION(void, newQpGenSparse, (double **)(int)(int **) .... (int *) );
相关文章:
- 当vector是tje全局变量时,c++中vector的内存管理
- 我有一个线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x8)错误.我认为这是由于内存管理不好.我可以
- C++将字符串传递给 C 库以进行内存管理
- 从函数返回时C++内存管理
- 函数指针和 lambda 的内存管理
- 自定义内存管理器在发布模式下工作正常,但在调试模式下则不然
- C++中的内存管理
- C和C++中的内存管理有什么区别
- 字符 * 未从重载运算符或内存管理问题正确返回
- 如何在源代码中使用执行策略检测 C++17 的扩展内存管理算法的可用性?
- 底层指针和内存管理
- 智能指针,避免使用QNetworkAccessManager时进行手动内存管理
- c++中的内存管理问题
- 使用矢量时的内存管理
- 循环和内存管理中的指针算术C++?
- C++堆栈内存管理问题
- C 内存管理中的课程如何管理 - 研究
- 不可变数据模型的内存管理
- C++ 使用数组初始化时的 STL 向量内存管理
- SFML 纹理内存管理