Почему Visual C++ 2010 жалуется на «Использование неинициализированной памяти»?

У меня есть функция, которая принимает указатель на буфер и размер этого буфера (через указатель). Если буфера недостаточно, он возвращает значение ошибки и устанавливает требуемую длину в выходном параметре:

// 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 и помещает соответствующий требуемый размер в выходной параметр. - person Roger Lipscombe; 13.01.2010