calloc в возвращаемом значении параметра функции - PullRequest
0 голосов
/ 02 июня 2011

Мой код отлично работает на моем компьютере и других тестовых виртуальных машинах, но на компьютере моего клиента поведение не определено.Иногда, после нажатия OK на MessageBox в _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(&sTemp);
    MessageBox(0,sTemp,L"",0);
    free(sTemp);
    return 0;
}

Я пытался удалить последний free и даже поставил sTemp=NULL; после free, но возникает та же проблема.

Спасибо!

1 Ответ

1 голос
/ 02 июня 2011

Я вижу две проблемы, и обе они касаются длины возможного значения "VS90COMNTOOLS".

Первая GetEnvironmentVariable используется неправильно.Если переданный буфер недостаточно велик для хранения значения переменной среды, возвращаемое значение GetEnvironmentVariable - это количество символов, необходимое для хранения значения, включая нулевой терминатор.Если функция завершается ошибкой из-за того, что буфер недостаточно велик, возвращаемое значение не равно нулю, как предполагает ваш код.Вы должны увидеть, является ли возвращаемое значение 0 (для сбоя, например, не найден) или оно больше, чем размер буфера, переданного (слишком мало).

Во-вторых, dwSize используется для выделения1024 символа для sGetVS, где в буфере sBuffEnv выделено 4097 символов.Если значение, возвращаемое в sBuffEnv, превышает 1024 символа, вы будете переполнять буфер, выделенный для sGetVS, при выполнении StringCchCopy, что приведет к серьезному повреждению кучи, вызывающему прерывание работы вашего приложения (или любое другое странное действие).

Обновление

Если переменная среды слишком велика, чтобы поместиться в предоставленном буфере, возвращаемое значение из GetEnvironmentVariable - это размер, необходимый для того, чтобы буфер мог содержатьпеременная.В этом случае содержимое sBuffEnv не определено (может быть нетронутым, может быть усеченным значением с или без нулевого терминатора, содержать мусор ..., нет никаких гарантий, что оно может содержать после вызова).Если это так, вы можете использовать неверные данные, когда делаете StringCchCopy.

...