0

I wrote very simple function that should copy n characters from source buffer to destination buffer. However, program crashes with write access violation exception. I am not sure where is the problem.

int main()
{
    char* str1 = "onefive";
    char* str2 = "two";

    char* dest = memcpy(str1, str2, strlen(str2));
    // expected output is "twofive"
}
void* memcpy(void* dest, const void* src, size_t n)
{
    char* cdest = (char*)dest;
    const char* csrc = (char*)src;

    for (int i = 0; i < n; i++)
        cdest[i] = csrc[i]; // write access violation (cdest)
    return cdest;
}
user10203585
  • 105
  • 6
  • 1
    Show a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example) that demonstrates the bug. The code snippet currently lacks the calling code. – kotatsuyaki Dec 17 '22 at 14:13
  • 3
    String literals in C are read-only. You cannot change data which `str1`/`str2` point to. – yeputons Dec 17 '22 at 14:25
  • @yeputons what would be a proper way to write that part of function? – user10203585 Dec 17 '22 at 14:34
  • 1
    If you want to write into `str1`, change it to something like `char str1[N+1]` where N is the max number of characters you want to support for the copy.` – wohlstad Dec 17 '22 at 14:44
  • 1
    A side note: I would call a function you implement yourself `memcpy` to avoid colission with the standard `memcpy`. – wohlstad Dec 17 '22 at 14:46
  • While I added extra information about string concatenation to my answer, it is to be noted that OP is only trying to _overwrite_ the beginning of the existing string... – Dúthomhas Dec 17 '22 at 14:53
  • Does this answer your question? [Why can I not modify a string literal in c?](https://stackoverflow.com/questions/58584310/why-can-i-not-modify-a-string-literal-in-c) – Gerhardh Dec 17 '22 at 15:12

1 Answers1

2

Literals and mutability

It is an artifact of the language (due to its age) that

char * s = "Hello world";

is valid. The "Hello world" is a string literal, which is immutable. In order to not break old code, the C Standard still allows this syntax instead of requiring the more correct:

const char * s = "Hello world";

In order to get a mutable array of characters (aka string), you need to signal it with the following syntax:

char s[] = "Hello world";

This causes you to get a copy of the immutable literal string in your own local variable s, which is a mutable (non-const) array of twelve characters (a string of 12 characters — the eleven for “hello”, space, and “world” plus the terminating nul character).

String Size

You can modify the content of the local string, but again you only have twelve characters to do it with. To concatenate strings you need an array (string) large enough to contain the results. Hence, you should specify a string size constraint at declaration:

#include <stdio.h>
#include <string.h>

int main(void)
{
  char s[100] = {0};  // the target string, non-const/mutable, 100 characters max!

  const char * a = "Hello";  // reference to immutable string
  char b[] = "World";        // mutable copy of a string

  strcpy( s, a );            // copy to our large local string s
  strcat( s, " " );          // (append a space to separate words)
  b[0] = 'w';                // changes b’s “World” to “world” (’cause b is a copy!)
  strcat( s, b );            // append a copy of b to the end of s
  strcat( s, "!" );          // some umph

  printf( "%s\n", s );       // ta-da!

  return 0;
}

Remember, arrays are just a whole bunch of values in a row. The values can be either const or not, and you must have enough room to keep all the values you wish to use.

Dúthomhas
  • 8,200
  • 2
  • 17
  • 39