3

我有一个必须传递给它的 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* 数组(因为在返回之前必须将其删除从函数中避免内存泄漏)。

4

3 回答 3

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!)

于 2012-05-03T12:56:49.383 回答
2

必须在从函数返回之前删除 this 以避免内存泄漏

这并不完全正确:尽管您最终需要使用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;
于 2012-05-03T12:47:34.357 回答
0

通常的方法是使用一个管理数组生命周期的对象(例如 astd::vector<char*>或 a 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());
于 2012-05-03T12:48:18.620 回答