Search code examples
c++crashmemcpychar-pointer

memcpy causing program to crash with initialized destination


I was working on a larger program and memcpy was causing it to crash. I replicated the situation in a small program and it does the same thing. I noticed that for some reason this program runs fine

// Runs fine
#include <iostream>

int main() {
    char* s1 = "TEST"; // src
    char* s2; // dest

    memcpy(s2, s1, strlen(s1) + 1);
    std::cout << s2 << std::endl; // Should print "TEST"

    return 0;
}

But this program crashes

// Crashes
#include <iostream>

int main() {
    char* s1 = "TEST"; // src
    char* s2 = ""; // dest - Note the small change

    memcpy(s2, s1, strlen(s1) + 1);
    std::cout << s2 << std::endl; // Should print "TEST"

    return 0;
}

I'm not sure why this is happening. Can someone please explain why it is crashing?

Thanks!


Solution

  • Both programs have undefined behavior. So if the first one does not crash (it dereferences an uninitialized pointer!), it is just that you are unlucky.

    The destination (first argument to memcpy) should be an allocated and writable zone. Either a local array (or some pointer to a local data on the stack, perhaps in some caller's frame) - or some pointer to global or static data - :

    char arr[32];
    memcpy (arr, s1, strlen(s1)+1);
    

    or a heap-allocated zone:

    char*ptr = malloc(32);
    if (!ptr) { perror("malloc"); exit(EXIT_FAILURE); };
    memcpy (ptr, s1, strlen(s1)+1);
    

    Notice that generally literal strings like "ABC" are not writable. They sit in the read-only data segment.

    the above is C code. If you want C++ code, use new (but in C++, you should use std::string)

    BTW, be very careful to avoid buffer overflows. The code above works because in that case strlen(s1) is less than 31.