#calloc
#calloc
Вопрос:
Мой код отлично работает на моем компьютере и других тестовых виртуальных машинах, которые у меня есть, но на компьютере моего клиента поведение не определено. Иногда, после нажатия OK в окне сообщений в _tmain, скомпилированный exe-файл использует 100% процессора, а иногда он вылетает из строя.
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
DWORD GetVS(TCHAR **sGetVS)
{
DWORD dwSize = 1024;
*sGetVS = (TCHAR *) calloc(dwSize,sizeof(TCHAR));
// Buffer for the environment variable value.
TCHAR *sBuffEnv = (TCHAR *) calloc(4096 1,sizeof(TCHAR));
DWORD dwRet = GetEnvironmentVariable(L"VS90COMNTOOLS", sBuffEnv, 4096);
if (dwRet)
{
StringCchCopy(*sGetVS,_tcslen(sBuffEnv) 1,sBuffEnv);
MessageBox(0,sBuffEnv,*sGetVS,0);
_tcslwr_s(*sGetVS,_tcslen(*sGetVS) 1); // 1 is required for the null char
}
free(sBuffEnv);sBuffEnv=NULL;
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR *sTemp = NULL;
GetVS(amp;sTemp);
MessageBox(0,sTemp,L"",0);
free(sTemp);
return 0;
}
Я попытался удалить последнее free
и даже поставил sTemp=NULL;
после free
, но возникает та же проблема.
Спасибо!
Ответ №1:
Я вижу две проблемы, и обе они связаны с длиной возможного значения "VS90COMNTOOLS"
.
Первый GetEnvironmentVariable
используется неправильно. Если переданный буфер недостаточно велик для хранения значения переменной среды, возвращаемое значение GetEnvironmentVariable
— это количество символов, необходимых для хранения значения, включая нулевой ограничитель. Если функция завершается с ошибкой из-за недостаточного размера буфера, возвращаемое значение не равно нулю, как предполагается в вашем коде. Вы должны посмотреть, равно ли возвращаемое значение 0 (при сбое, например, не найдено) или оно больше размера переданного буфера (слишком мало).
Во-вторых, dwSize
используется для выделения 1024 символов для, sGetVS
где буферу sBuffEnv
выделено 4097 символов. Если значение, возвращаемое в sBuffEnv
, превышает 1024 символа, вы переполните буфер, выделенный для sGetVS
выполнения StringCchCopy
, что приведет к повреждению кучи, в результате чего ваше приложение будет прервано (или сделает любое количество странных вещей).
Обновить
Если переменная среды слишком велика, чтобы поместиться в поставляемом буфере, возвращаемое значение из GetEnvironmentVariable
— это размер, необходимый для того, чтобы буфер мог содержать переменную. В этом случае содержимое sBuffEnv
не определено (может быть нетронутым, может быть усеченным значением с нулевым ограничителем или без него, содержать мусор …, нет никаких гарантий, что оно может содержать после вызова). Если это так, вы могли бы использовать неверные данные при выполнении StringCchCopy
.
Комментарии:
1. Re: GetEnvironmentVariable, переменная представляет собой путь, а MAX_PATH определен как 260, поэтому 1024 будет содержать его, поэтому sBuffEnv никогда не будет иметь значения > 1024 символов. Я получал значение, передавая «0» в API, и это не имело никакого значения для клиента.
2. Конечно, если переменная действительно содержит допустимый путь. Ваш код предполагает, что это так, и не предпринимает шагов, чтобы убедиться, что это правильно. Я мог бы очень легко взломать этот код, если бы был тестировщиком. Предполагая, что входные данные верны, я не вижу проблемы в этой части кода.
3. Помимо тестирования правильного размера буферов, можете ли вы вообще помочь в отношении того, почему у кода возникают проблемы после MessageBox в _tmain? Как я уже упоминал, иногда он использует 100% процессора, а в других случаях просто выдает общую ошибку / GPF.
4. Вы уверены, что
"VS90COMNTOOLS"
существует и правильно определено на компьютере клиента? Это фактический код, который подвергается бомбардировке, или это вырезано из большей кодовой базы? То, что вы описываете, действительно звучит для меня как повреждение памяти, причины которого я изложил здесь.5. Да, это определено на клиентском компьютере. Да, это фактический код, который подвергается бомбардировке. Переменная среды на компьютере клиента выглядит следующим образом: VS90COMNTOOLS=C:Program Files (x86) Microsoft Visual Studio 9.0 Common7 Tools