strcpy_s causes "heap corruction detected" error when deleting buffer

    char* buf = (char*)malloc(sizeof(char) * 11);
    for (int i = 0; i < 5; i++)
        buf[i] = '?';
    strcpy_s(buf + 5, sizeof(char) * 11, "apple");
    buf[10] = '\0';

I have the code above. It says "heap corruction detected" when buf is freed. I want to use strcpy_s to write to the last 5 characters of buf. From what I read and understood, the size argument should be the size of the destination buffer but I also tried doing

strcpy_s(buf + 5, 5, "apple");

But in this case it says buffer is too small. What should I do?

>Solution :

strcpy_s(buf + 5, sizeof(char) * 11, "apple"); tells strcpy_s there are 11 bytes available at buf + 5. That is false; 11 bytes were reserved at the location where buf points. Starting from buf + 5, there are only 6 bytes available.

This strcpy_s overruns the array and writes into other memory, corrupting the so-called heap. The reason for this is that, although one might think strcpy_s copies individual bytes until a terminating null character is seen, the specification for the routine allows it to use the entire destination buffer regardless of the length of the source string. Specifically, C 2018 K. 5 says:

All elements following the terminating null character (if any) written by strncpy_s in the array of s1max characters pointed to by s1 take unspecified values when strncpy_s returns a nonzero value.

The purpose of that is to allow an optimized implementation of strncpy_s to copy large groups of data than individual bytes.

(One might wonder how one can avoid overrunning the terminating null in the source array when copying such groups of data. An answer for this is that, in common C implementations, it is safe to copy aligned words because the memory protections operate in page-aligned units. So a strcpy_s implementation may copy whole aligned words from the source to the destination as long as they fit into the destination and no null character has yet been seen in a word.)

Leave a Reply