Защо Visual C++ 2010 се оплаква от „Използване на неинициализирана памет“?

Имам функция, която взема указател към буфер и размера на този буфер (чрез указател). Ако буферът не е достатъчно голям, той връща стойност за грешка и задава необходимата дължина в out-param:

// FillBuffer is defined in another compilation unit (OBJ file).
// Whole program optimization is off.
int FillBuffer(__int_bcount_opt(*pcb) char *buffer, size_t *pcb);

Аз го наричам така:

size_t cb = 12;
char *p = (char *)malloc(cb);
if (!p)
    return ENOMEM;

int result;
for (;;)
{
    result = FillBuffer(p, &cb);
    if (result == ENOBUFS)
    {
        char *q = (char *)realloc(p, cb);
        if (!q)
        {
            free(p);
            return ENOMEM;
        }

        p = q;
    }
    else
        break;
}

Visual C++ 2010 (с максимален анализ на кода) се оплаква от 'warning C6001: Using uninitialized memory 'p': Lines: ...'. Той отчита номера на редове, покриващи почти цялата функция.

Visual C++ 2008 не го прави. Доколкото мога да преценя, този код е ОК. какво ми липсва Или какво липсва на VC2010?


person Roger Lipscombe    schedule 13.01.2010    source източник
comment
Към кой ред е приписано предупреждението?   -  person j_random_hacker    schedule 13.01.2010
comment
Това е, което получих, когато го опитах: d:\testpro\sss\sss\sss.cpp(27): предупреждение C6001: Използване на неинициализирана памет 'p': Редове: 13, 14, 16, 21, 22, 24, 25, 31, 21, 22, 24, 25, 31, 21, 22, 24, 25, 27 Общо взето всички редове във функцията   -  person Arve    schedule 13.01.2010
comment
Хм, тогава съм озадачен. Предполагам, че статичният анализ на VC++ не знае за (добре дефинираното) поведение на realloc(), когато p е NULL (т.е. ако оригиналният malloc() е неуспешен). Или самият FillBuffer() се държи зле в този случай? В кой случай VC++ е на топката?   -  person j_random_hacker    schedule 13.01.2010
comment
FillBuffer е в отделен OBJ файл, така че VC++ няма начин да разбере какво прави освен прототипа. Оптимизацията на цялата програма е изключена.   -  person Roger Lipscombe    schedule 13.01.2010
comment
О, и проверката на резултата от malloc също не го коригира. Леко актуализирах въпроса.   -  person Roger Lipscombe    schedule 13.01.2010
comment
Свързан въпрос е stackoverflow.com/questions/33513003.   -  person JdeBP    schedule 28.06.2018


Отговори (2)


Това трябва да е грешка във Visual Studio 2010. Опаковането malloc премахва предупреждението, както в следния тестван код:

char * mymalloc(int i)  
{  
    return (char *) malloc(i);  
}

// ...

void *r = mymalloc(cb);

char *p;

p = (char *) malloc(cb);
person Arve    schedule 13.01.2010
comment
Ти си прав. Моя грешка, трябва да е char *p = NULL, за да изчезнат предупрежденията. (Вероятно трябва да гласувам против себе си). (Мисля, че направих повторно изграждане, а не анализ по погрешка) - person Arve; 13.01.2010
comment
Благодаря за потвърждението. Повдигнах грешка в Connect. - person Roger Lipscombe; 13.01.2010
comment
Ако не сте доволни от собствения си отговор, можете да го редактирате или премахнете и да улесните следващите посетители (уверете се, че разбират, че отговорът не е такъв, дори и да не влизат в коментари) - person David Rodríguez - dribeas; 13.01.2010

Не сте проверили дали първият malloc() е наред. Това води до предупреждението.

person alemjerus    schedule 13.01.2010
comment
malloc винаги ще връща нещо, така че p винаги ще получава стойност. Не мисля, че това е проблемът - person Arve; 13.01.2010
comment
FillBuffer приема NULL и поставя подходящия изискван размер в out-param. - person Roger Lipscombe; 13.01.2010