C++ 为什么CreateProcess API调用会导致内存访问冲突?
我有一个应该启动另一个进程的函数:C++ 为什么CreateProcess API调用会导致内存访问冲突?,c++,winapi,createprocess,C++,Winapi,Createprocess,我有一个应该启动另一个进程的函数: DWORD WINAPI StartCalc(LPVOID lpParam) { STARTUPINFOW info; PROCESS_INFORMATION processInfo; std::wstring cmd = L"C:\\Windows\\System32\\calc.exe"; BOOL hR = CreateProcessW(NULL, (LPWSTR)cmd.c_str(), NULL, NULL, T
DWORD WINAPI StartCalc(LPVOID lpParam) {
STARTUPINFOW info;
PROCESS_INFORMATION processInfo;
std::wstring cmd = L"C:\\Windows\\System32\\calc.exe";
BOOL hR = CreateProcessW(NULL, (LPWSTR)cmd.c_str(), NULL, NULL, TRUE, 0, NULL, NULL,
&info, &processInfo);
if (hR == 0) {
DWORD errorMessageID = ::GetLastError();
printf("Error creating process\n");
return 1;
}
return 0;
}
我在ntdll.dll“访问冲突读取位置0xFFFFFFFFFFFFFF”中遇到异常。我知道有几个常见的错误可能会导致这种情况:
- 不一致的呼叫约定。我正在使用stdcall
- 编码问题。我将字符串存储为宽字符
- 问题发生在x64和x86版本中
- 当我尝试创建其他Windows进程时会出现问题
cmd.c_str()
转换为(LPWSTR)
,这实际上不是问题,该部分看起来很好。我需要初始化STARTUPINFO结构:STARTUPINFO={0}代码>
那是演员阵容。一个伟大的经验法则是“发现演员,你发现错误”
这是真的<必须向code>CreateProcessW
传递一个可写字符串。这意味着,没有文字,也没有c_str()
result
从文件中:
此函数的Unicode版本,CreateProcessW
,可以修改此字符串的内容。因此,此参数不能是指向只读内存(例如常量变量或文字字符串)的指针。如果此参数是常量字符串,则函数可能会导致访问冲突
传递一个真正的非-常量
指针,不要玩隐藏-常量
&cmd[0]
应该可以工作,这保证是一个可写字符串。为了超级安全,请将wstring
容量增加到所需容量之外,因为CreateProcessW
将使用它作为工作缓冲区
那是演员阵容。一个伟大的经验法则是“发现演员,你发现错误”
这是真的<必须向code>CreateProcessW传递一个可写字符串。这意味着,没有文字,也没有c_str()
result
从文件中:
此函数的Unicode版本,CreateProcessW
,可以修改此字符串的内容。因此,此参数不能是指向只读内存(例如常量变量或文字字符串)的指针。如果此参数是常量字符串,则函数可能会导致访问冲突
传递一个真正的非-
常量
指针,不要玩隐藏-常量
&cmd[0]
应该可以工作,这保证是一个可写字符串。为了超级安全,请将wstring
容量增加到所需容量之外,因为CreateProcessW
将使用它作为工作缓冲区。不完全重复,因为存在另一个错误访问冲突写入位置。。在这里访问读取位置。cmd.c_str()实际上是可写内存,它不指向字符串文字(它复制到分配的内存)。错误的真正来源是什么-未初始化STARTUPINFOW信息
同样,如果我们有确切的应用程序路径,为什么不将其作为CreateProcessW
的第一个参数传递呢?在本例中(显式路径),2参数可以是只读字符串,因为当我们有path时,不需要为临时隔离应用程序名解析和修改命令行STARTUPINFO={sizeof(info)}代码>必须为空。若你们有确切的应用程序路径,那个么最好将它作为一个参数传递给创建流程。即使您只有名称-最好先直接调用SearchPath
并将结果传递给1个参数。不完全重复,因为存在另一个错误访问冲突写入位置。。在这里访问读取位置。cmd.c_str()
实际上是可写内存,它不指向字符串文字(它复制到分配的内存)。错误的真正来源是什么-未初始化STARTUPINFOW信息
同样,如果我们有确切的应用程序路径,为什么不将其作为CreateProcessW
的第一个参数传递呢?在本例中(显式路径),2参数可以是只读字符串,因为当我们有path时,不需要为临时隔离应用程序名解析和修改命令行STARTUPINFO={sizeof(info)}代码>必须为空。若你们有确切的应用程序路径,那个么最好将它作为一个参数传递给创建流程。即使您只有名称-最好先直接调用SearchPath
并将结果传递给1个参数。
BOOL hR = CreateProcessW(NULL, (LPWSTR)cmd.c_str(), NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo);
^^^^^