几次调用后,外部程序的执行失败

时间:2013-09-06 11:47:54

标签: c++

我想调用外部程序将BMP转换为DDS文件,但经过几次调用后它一直崩溃。我尝试了ShellExecuteCreateProcessor。这是ShellExecute的示例:

path = "C:\\pictures";
file = "C:\\pictures\\test.bmp";
string cmd = "-f BC1_UNORM -o " + path + " " + file;
char* cmdConvert= new char[cmd.size()];
strcpy(cmdConvert, cmd.c_str());
int buffSize = (int)strlen(cmdConvert) + 1;
LPWSTR cmdL= new wchar_t[buffSize];
MultiByteToWideChar(CP_ACP, 0, cmdConvert, buffSize, cmdL, buffSize);

SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShEecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = _T("C:\\Texconv\\texconv.exe");
ShExecInfo.lpParameters = cmdL;
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_HIDE;
ShExecInfo.hInstApp = NULL;

ShellExecuteEx(&ShExecInfo);
WaitForSingleObject(ShExecInfo.hProcess,INFINITE);
CloseHandle(ShExecInfo.hProcess);

delete convertMe;
delete gah;

它在ShellExecuteEx(&ShExecInfo)之后直接崩溃。必须有一些竞争条件(或类似的东西),因为它在调试器中运行时不会崩溃(我使用的是VS2012)。

1 个答案:

答案 0 :(得分:2)

你在第4行缺少终点零:

char* cmdConvert= new char[cmd.size()];

写:

char* cmdConvert= new char[cmd.size()+1];

正如我现在认为的那样,由于终端零字符,空字符串缓冲区长一个字节。 cmd.size()不包含此终端字符。对于sring缓冲区,您必须在字符串长度中添加一个字节。 发布版本中的崩溃是在缓冲区之后覆盖某些内容的结果。在调试模式下,new运算符在分配缓冲区的开头和结尾填充一些字节以支持缓冲区覆盖检测,这就是它在调试中运行的原因。