3

外部プログラムを呼び出して BMP を DDS ファイルに変換したいのですが、数回呼び出した後、常にクラッシュします。ShellExecuteと の両方を試しましCreateProcessorた。ここでの例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 を使用しています)、いくつかの競合状態 (またはこのようなもの) が存在する必要があります。

4

1 に答える 1

2

4 行目にターミナル ゼロがありません。

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

書きます:

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

すでに考えているように、空の文字列バッファーは、終端のゼロ文字のために 1 バイトの長さです。cmd.size() には、この終端文字は含まれません。sring バッファーの場合、文字列の長さに 1 バイトを追加する必要がありました。リリース ビルドでのクラッシュは、そのバッファーの後に何かを上書きした結果です。デバッグ モードでは、新しい演算子は、割り当てられたバッファーの最初と最後にいくつかのバイトを埋め込み、バッファーの上書き検出をサポートします。これが、デバッグで実行される理由です。

于 2013-09-06T11:53:44.920 に答える