缓冲区溢出?

dth*_*guy 7 c++ memory

我试图将char *的向量转换为char指针的数组,但遇到此烦人的错误,无法弄清楚自己在做什么错。

char** Parse::toCommand(std::vector<char*> command) {
    char** array = new char* [command.size()];
    for (int i = 0; i < command.size(); i++) {
        array[i] = command[i];
    }

    return array;
}
Run Code Online (Sandbox Code Playgroud)

我收到此警告,导致我的程序无法运行。

 Buffer overrun while writing to 'array':  the writable size is 'command.public: unsigned int __thiscall std::vector<char *,class std::allocator<char *> >::size(void)const ()*4' bytes, but '8' bytes might be written.
Run Code Online (Sandbox Code Playgroud)

char *当然是一个交流字符串。

向量中的字符串是使用strtok_s分割的一部分字符串。我通过使用string :: copy()将每个转换为ac str以获得非常量c字符串,并使用std :: string的构造函数获取常规字符串来摆脱每个字符串末尾的Null。然后,我弹出后背以摆脱零位。

我的最终目标是我想要一个c字符串数组,以便可以将其传递给execvp()

for (int i = 0; i < exes.size(); i++) {  //Separate each executable and argument list into vector of char* and push that to 2d vector of char*

        char* arg = exes[i]; //arg = the entire string executable and arguments
        std::vector <char*> argV;

        char* place = NULL;

        ptr3 = strtok_s(arg, " ", &place);

        while (ptr3 != NULL) {

            if (*ptr3 == '"') {//if beginning of remaining char* begins with ", push char*
                std::string temp;
                temp.push_back(*ptr3);
                ptr3 = strtok_s(NULL, "\"", &place);
                temp.append(ptr3);
                temp.pop_back();
                temp.push_back('"');
                char* cstr = new char[temp.size()];
                temp.copy(cstr, temp.size(), 0);
                argV.push_back(cstr);
            }
            else if (*ptr3 == '#') {
                break;
            }
            else {
                std::string temp(ptr3);
                temp.pop_back();
                char* cstr = new char[temp.size()];
                temp.copy(cstr, temp.size(), 0);
                argV.push_back(cstr);
            }
            ptr3 = strtok_s(NULL, " ", &place);
        }

        argV.push_back(NULL);
        args.push_back(argV);
    }

    for (int i = 0; i < args.size(); i++) {
        char** command = this->toCommand(args[i]);
        commands[i] = new COM(command);
    }
Run Code Online (Sandbox Code Playgroud)

argV是a vector<vector<char*>>

650*_*502 0

问题不在于您显示的代码,而在于其他地方。您的代码为指针分配空间,然后分配这些指针。

char *然而,最大的问题是:您是否真正评估过使用来表示字符串而不是 的优缺点std::string?看来是来找麻烦的……

另外,您的代码已经依赖于std::vector,为什么使用手动分配char **而不是std::vector<std::string>?例如,根据char**您使用它的方式,您无法知道有多少个指针(无法以可size()移植的方式实现)。

编辑

从评论看来你需要打电话execvp。从手册页:

execv()、execvp() 和 execvpe() 函数提供指向以 null 结尾的字符串的指针数组,这些字符串表示新程序可用的参数列表。按照惯例,第一个参数应该指向与正在执行的文件关联的文件名。

指针数组必须以 NULL 指针终止。

注意最后一句话。您需要将一个额外的指针设置为 NULL,以便命令可以知道字符串列表的终止位置。

  • 那么你可能需要分配一个额外的指针并将其设置为“nullptr” (2认同)