[英]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.