如何为字符串数组实例变量动态分配空间? 我试图用C++创建一个简单的shell程序。我有一个命令行类,其中包含参数数量的实例变量和这些参数的数组 private: int argc; char *argv[];

如何为字符串数组实例变量动态分配空间? 我试图用C++创建一个简单的shell程序。我有一个命令行类,其中包含参数数量的实例变量和这些参数的数组 private: int argc; char *argv[];,c++,arrays,C++,Arrays,以下是在命令行类中定义构造函数的代码: CommandLine::CommandLine(istream& in) { string cmd; getline(in, cmd); vector<string> args; string arg; istringstream iss(cmd); while( iss >> arg ) args.push_back(arg); argc = args.s

以下是在命令行类中定义构造函数的代码:

 CommandLine::CommandLine(istream& in) {    
    string cmd;
    getline(in, cmd);
    vector<string> args;
    string arg;
    istringstream iss(cmd);
    while( iss >> arg ) args.push_back(arg);
    argc = args.size();
    argv = (char*) malloc(argc*sizeof(argv));
    }
CommandLine::CommandLine(istream&in){
字符串cmd;
getline(in,cmd);
向量args;
字符串arg;
istringstream iss(cmd);
while(iss>>arg)args.push_back(arg);
argc=args.size();
argv=(char*)malloc(argc*sizeof(argv));
}
当我尝试编译时,会收到以下错误消息:

CommandLine.cpp:在构造函数“CommandLine::CommandLine(std::istream&)”中:
CommandLine.cpp:29:41:错误:将“char*”赋值给“char*[0]”时类型不兼容。

您应该使用:
char**argv

分配如下:

argv = new char*[argc]; //needed to be deleted at destructor
for (int i=0; i< argc; i++){
   argv[i]= strdup(args[i].c_str()); //needed to be freed at destructor
}
argv=newchar*[argc]//需要在析构函数中删除
对于(int i=0;i

更好的解决方案是使用
向量args
作为成员而不是
argv

更改您的成员定义,从:

char*argv[]

char**argv

对于您的任务,它们在功能上是兼容的。然后,按以下方式分配空间:

argc = args.size();
argv = (char**)malloc(argc * sizeof(char*));

if(!args.empty())
{
  for(int n = 0; n < argc; ++n)
  {
    const string& src = args[n];
    char*& current = argv[n];

    current = (char*)malloc((src.length() + 1) * sizeof(char));
    memcpy(current, src.c_str(), (src.length() + 1) * sizeof(char));
  }
}
argc=args.size();
argv=(char**)malloc(argc*sizeof(char*);
如果(!args.empty())
{
对于(int n=0;n

但是,我不明白为什么不能使用类型为
std::vector
的成员,因为您已经使用它来临时存储命令行参数。这将是更好的解决方案(并且不容易出错)。

使用
malloc
new
创建
argv*
数组的想法是一种混乱的方法,可能会导致内存泄漏

使用
malloc
new
避免内存泄漏或直接分配内存的方法如下:

首先,存储字符数组向量和指向字符的指针向量:

class CommandLine
{
    typedef std::vector<char> CharArray;
    typedef std::vector<CharArray> ArgumentVector;
    ArgumentVector argvVec;
    std::vector<char *> argv;
    public:
        CommandLine(std::stream& in);
};
请注意,没有调用
malloc
、没有调用
new
、没有内存泄漏等。唯一的缺点是您需要两个向量,一个用于字符串数据,另一个用于保存指向每个字符串项的指针,后者用于“类main”函数所需的
char**
类型(在上面的示例中,“main”函数只是打印出给出的参数列表)

现在,当
命令行
对象超出范围时,所有元素都会被清除,因为字符串和指针存储在向量中。没有内存泄漏,没有指向管理不当的指针,等等


实例:

此外,第29行是构造函数中的最后一行,即“argv=(char*)malloc(argc*sizeof(argv));”
char*argv[]这是非标准C++。数组必须使用编译时表达式声明,而不是空的。您可以简单地使用<代码> STD::vector < /代码>,然后给出给您的问题是:代码> ARGV。调整大小(ARCC)。
而不是
malloc
在这里:
std::vector
…当我做出您建议的更改并使用上面的代码时,我收到以下错误消息:CommandLine.cpp:在构造函数的CommandLine::CommandLine(std::istream&)“:CommandLine.cpp:23:44:错误:将“char**”赋值给“char**[0]”命令行时类型不兼容。cpp:30:26:错误:从“char**”类型的表达式初始化“char*&”类型的引用无效。这些错误意味着您没有正确更新代码。如果
argv[n]
被检测为类型
char**
argv
成员必须声明为
char**argv[]
。它必须是
char**argv
(不带括号)。谢谢,这样做了!忘记了那个简单的修复
#include <vector>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
//...
using namespace std;

void my_command_line(int numArgs, char** args);

CommandLine::CommandLine(std::istream& in)
{
    string cmd;
    getline(in, cmd);
    string arg;
    istringstream iss(cmd);
    while (iss >> arg)
    {
        // create an entry in our string vector.  This basically 
        // replaces the call to allocate for each new string
        argvVec.push_back(CharArray(arg.begin(), arg.end()));

       // make sure we null-terminate the last string we added.
        argvVec.back().push_back(0);

        // add the pointer to this string to the argv vector
        argv.push_back(argvVec.back().data());
    }

    // call the alternate command-line function
    my_command_line(argv.size(), argv.data());
}

void my_command_line(int numArgs, char** args);
{
    for (int i = 0; i < numArgs; ++i)
        std::cout << "argument " << i << ": " << args[i] << std::endl;
}

int main()
{
    ifstream ifs("Test.txt");
    CommandLine test(ifs);
}