2015-08-21 5 views
1

Малых бит коды:тетср Читаемого Диапазон

int main() 
{ 
    char buf[18]; 
    char buf2[18]; 
    int newlength = 16; 
    memset(buf, '0', 16); 
    for (int i = newlength; i < 18; i++) 
     buf[i] = 0x00; 

    memcpy(buf2, buf, 18); 

    return 0; 
} 

Сначала я хочу, чтобы установить часть массива до определенного значения, а затем я хотел бы, чтобы заполнить остальные с 0x00. Затем я хотел бы скопировать его в другой массив.

В MS VS2013 я получаю предупреждение как читаемый диапазон для buf между 0 и 15. (Анализ кода для предупреждений C/C++. C6385 Read Overrun) Почему? Does memcpy игнорирует бит, установленный в 0x00?

+1

Пожалуйста, предоставьте предупреждение. Кроме того, какой компилятор? – Barry

+1

Невозможно воспроизвести, я не вижу никаких предупреждений. Расскажите, пожалуйста, ваши параметры компилятора + версии + (или какой-либо инструмент, созданный предупреждением). Http: //coliru.stacked-crooked.com/a/90211ae6e2daa5c7 –

+0

И, кстати, есть ли веская причина, почему вы не используете 'std :: vector'? –

ответ

2

Это сообщение от анализатора кода, по-видимому, основано на принципе, что содержимое буфера будет определяться как результат от memset(). Он пропускает то, что цикл после memset() завершает этот ввод.

Если вы дважды щелкните предупреждение, вы можете получить выделение строк, рассматриваемых для запуска этого предупреждения.

Но код, который вы пишете, верен, поэтому вам не нужно беспокоиться о результате здесь. Электронная документация говорит «может быть» нет «будет»:

Это предупреждение означает, что машиночитаемый степень указанного буфера может быть меньше, чем индекс, используемый для чтения из него.

Дополнительные замечания:

При принятии того, что происходит на более очевидным для анализатора, она по-прежнему приносит те же оскорбительные предупреждения:

memset(buf, '0', 16); 
    memset(buf + 16, 0x00, 2); // for replacing the loop 

В этом случае анализатор замечает второй memset(). Но поскольку он не влияет на buf с самого начала, он как вход/выход в буферную операцию без учета дополнительной длины.

Даже этот вид более-precautiononous код поднимает предупреждение:

memset(buf, 0x00, sizeof(buf)); // completeky initalize the buffer 
    memset(buf, '0', 16);    // overwrite just the beginning 

Здесь, кажется, что как только memxxx() операция цели Бегин буфера, длина этой операции считается подошва инициализированная часть.

Итак, да предупреждение раздражает, но доверяйте своему коду. Я мог бы только избавиться от предупреждения, сделав действительно странно в unefficient кодирования:

memset(buf, 0x00, sizeof(buf)); // 18 bytes get initalized 
    memset(buf + 1, '0', 15);   // not begin of buffer 
    buf[0] = '0';      // not a memxxx() operation 

К сожалению, конфигурация анализатора не позволяет отключить только это одно правило, но и весь набор правил проверки безопасности.

+0

Я вижу, что memcpy работает нормально, мне просто не нравится, что это дает мне предупреждение. : \ Мне не нравится «возможно», но я думаю, что так и будет. Спасибо :) – pistachiobk

+1

@pistachiobk Я немного поиграл, чтобы узнать, как избежать предупреждения (см. Редактирование): это правило предупреждения действительно недостаточно определено. Его единственное использование - привлечь внимание к потенциальным рискам, которые могут потребоваться для дальнейшего анализа. – Christophe

+1

Переключение memcpy (buf2, buf, 18); с std :: copy (buf, buf + 18, buf2); очищает предупреждение. В этом случае проблема должна быть только memcpy/memset. – pistachiobk

0

Кажется, ошибка в компилятор/ворса инструмента (зависит от того, кто показывает предупреждение)

-1

Вы инициализацией 16 байт. Вы получаете доступ к 18 байтам. Кажется, кажется, что доступ читается, хотя он не должен.

+0

Я инициализирую последние два байта в цикле for после memset. – pistachiobk

+0

Я получаю это; поэтому я говорю: «Кажется, кажется, что доступ читает». Я просто не уверен, почему это так кажется. – DrPizza