Search code examples
c++arraysmemcpymemset

Memcpy Readable Range


Small code bits:

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;
}

First I want to set a portion of an array to a specific value and then I would like to fill the rest with 0x00. Then I'd like to copy it to another array.

On MS VS2013, I receive a warning as readable range for buf to be between 0 and 15. (Code Analysis for C/C++ Warnings. C6385 Read Overrun) Why? Does memcpy ignore the bits set to 0x00?


Solution

  • This message from the code analyzer seems to be based on the principle that the buffer content would be defined alone as output from memset(). It misses the point that the loop after memset() completes this input.

    If you double click on the warning, you can get a highlighting of the lines considered for triggering this warning.

    But the code you write is correct, so you don't have to worry about the result here. The online documentation says "might" no "will" :

    This warning indicates that the readable extent of the specified buffer might be smaller than the index used to read from it.

    Additional remarks:

    When making what is going on more obvious for the analyzer, it still brings the same abusive warnings:

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

    In this case, the analyzer notices the second memset(). But as it doesn't affect buf from its beginning, it as an input/output to a buffer operation without taking into consideration the additional length.

    Even this kind over-precautiononous code raises the warning:

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

    Here, it seems that as soon as a memxxx() operation targets the begin of the buffer, the length of that operation is considered to be the sole initialized part.

    So, yes the warning is annoying, but trust your code. I could only get rid of the warning by making really weird an unefficient coding:

        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 
    

    Unfortunately the configuration of the analyzer doesn't allow to disable just this single rule, but the whole set of security verification rules.