[英]Buffer is overrun?
我正在尝试将 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;
}
我收到此警告,导致我的程序无法运行。
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.
char* 当然实际上是一个 c 字符串。
向量中的字符串是使用 strtok_s 分割的字符串片段。 我通过使用 string::copy() 将每个字符串转换为 c str 以获取非常量 c 来获取非常量 c 然后我弹出背面以摆脱 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);
}
argV 是一个vector<vector<char*>>
和
需要明确的是:此警告不是来自编译器,而是来自 Microsoft 代码分析器。
我做了一个使用 Visual Studio 2019 重现警告的完整示例。没有更多的字符串、指向指针的指针和其他糟糕的设计,并且警告仍然存在。
对我来说,代码是正确的,它只是 Microsoft 代码分析器中的一个错误,或者分析器过于谨慎。
#include <iostream>
#include <vector>
int* toCommand(std::vector<int> command)
{
int* array = new int [command.size()];
for (size_t i = 0; i < command.size(); i++) {
array[i] = command[i];
}
return array;
}
int main()
{
std::vector v{1,2,3};
int* foo = toCommand(v);
for (int i = 0; i < 3; i++)
std::cout << foo[i] << "\n";
}
警告来自 Microsoft 代码分析器,它也直接显示在 IDE 中:
这是显示警告的最简单示例:
int* Foo(int size)
{
int* array = new int [size];
array[1] = 1; // with array[0] = 1; the warning goes away
return array;
}
警告 C6386:写入“array”时缓冲区溢出:可写大小为“size*4”字节,但可能写入“8”字节。
问题不在于您显示的代码,而在于其他地方。 您的代码为指针分配空间,然后分配这些指针。
然而,最大的问题是:你真的评估过使用char *
来表示字符串而不是std::string
的优缺点吗? 看起来是在找麻烦...
此外,您的代码已经依赖于std::vector
,为什么要使用手动分配的char **
而不是std::vector<std::string>
? 使用char**
您使用它的方式,例如,您无法知道有多少指针(无法以可移植的方式实现size()
)。
从评论看来,您需要调用execvp
。 从手册页:
execv()、execvp() 和 execvpe() 函数提供了一个指向以 null 结尾的字符串的指针数组,这些字符串表示新程序可用的参数列表。 按照惯例,第一个参数应该指向与正在执行的文件关联的文件名。
指针数组必须由 NULL 指针终止。
注意最后一句话。 您需要将一个额外的指针设置为 NULL,以便命令可以知道字符串列表的终止位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.