我有一个C ++函数,我必须通过char* arguments[]
。该功能的原型如下:
void somefunc(char* arguments[])
要将上面的数组传递给这个函数,我从另一个函数生成这个数组,它可以返回这个char* array
输出,这看起来有点像这样。
char** genArgs(int numOfArgs,...)
{
va_list argList;
char** toRet = new char*[numOfArgs];
va_start (arguments, numOfArgs);
for(int cnt = 0; cnt < numOfArgs ; ++cnt)
toRet[cnt] = va_arg(argList, char*);
va_end(arguments);
}
我很困惑如何正确地编写上述函数,因为我将输入传递给函数,如:genArgs(3, a.c_str(), b.c_str(), c.c_str())
或genArgs(2, a.c_str(), b.c_str())
如何在不使用char **的情况下生成上面的char *数组(因为在从函数返回之前必须删除它以避免内存泄漏)。
答案 0 :(得分:3)
从genArgs
的声明中,无论何时调用genArgs
,您都知道要传递多少个参数。它是否正确?如果是这样(如果您使用的是C++11
),那么您可以在调用函数中使用std::array
。所以不要这样:
char** arglist = genArgs (4, "MyArg1", mYaRG2", "LastArg", 0) ;
somefunc (arglist) ;
delete[] arglist ;
你可以这样做:
#include <array>
std::array<char*, 4> arglist { "MyArg1", mYaRG2", "LastArg", 0 } ;
somefunc (&arglist[0]) ;
但是第一个解决方案确实没有错,除非你是C ++苦行僧。 (但是,您需要return toRet ;
中的genArgs
语句!)
答案 1 :(得分:2)
在从函数返回之前必须删除它以避免内存泄漏
这并不完全正确:虽然您最终需要delete[]
指向您使用new[]
分配的指针,但在退出分配的函数之前,您不一定要这样做发生了。
你可以这样做:
// This allocates args; we now own the pointer
char **argsToPass = genArgs(2, a.c_str(), b.c_str());
// Make the call as usual
somefunc(argsToPass);
// Now that args are no longer needed, we delete them:
delete [] argsToPass;
答案 2 :(得分:0)
通常的方法是使用管理数组生命周期的对象(例如std::vector<char*>
或std::unique_ptr<char*[]>
),然后返回该对象(以便最终释放内存将由类型系统保证):
std::vector<char*> genArgs(int numOfArgs,...)
{
std::vector<char*> toRet;
toRet.reserve(numOfArgs);
va_list argList;
va_start(argList, numOfArgs);
for(int cnt = 0; cnt < numOfArgs ; ++cnt) {
toRet.push_back(va_arg(argList, char*));
}
va_end(arguments);
return toRet;
}
要使用此功能,请执行以下操作:
somefunc(&genArgs(3, a.c_str(), b.c_str(), c.c_str()).front());