Why is a string copy function just assigning the pointer not working?

淺唱寂寞╮ 提交于 2019-12-02 07:34:27

问题


Consider this implementation of strcpy:

void my_strcpy(char target[], char source[])
{
   target = source;
}

int main(void)
{
   char target[20];
   char source[] = "Source String";

   my_strcpy(target, source);
   printf("Target: %s", target);

   return 0;
}

This doesn't work and its made me question my understanding of strings and arrays in C.

Here's my reasoning: target and source are really just pointers to the first elements of arrays, ie. target == &target[0] and source == &source[0]. When I set target = source, I'm pointing the pointer target at the same memory address where the pointer source is pointed at.

Now when I printf target, it should also print "Source String". But it doesn't.

Can someone explain why?


回答1:


void my_strcpy(char target[], char source[])
{
   target = source;
}

What you do here is, as you wrote, pass the pointers to the function. But the pointers themselves are passed by value, so the function has it's local copies of these pointers. The target inside the function stops existing as soon es the function exits.

To actually modify pointers in a function, you would have to pass a pointer to this pointer, e.g. like this:

void my_strcpy(char *target[], char source[])
{
   *target = source;
}

Note that this still wouldn't work with your program, because in main() you declare an array. The address of a declared array cannot be changed. This is because an array is not the same as a pointer (as you can often read in poorly written C tutorials) but is just implicitly converted to a pointer to its first element when you pass it to a function. So, writing char *target in your main(), this would work, calling the function like my_strcpy(&target, source);.

Also note that this is in no way a copy, so the naming of your function is semantically wrong. A real copy function would look like this:

void my_strcpy(char *target, const char *source)
{
   while (*target++ = *source++);
}

copying the individual characters until hitting a \0 character (then the expression would evaluate to 0 and the while loop would stop). This super-simple implementation leaves the burden to provide enough storage for target and to make sure source is actually 0-terminated to the caller, but it is indeed more or less what the standard C library's strcpy() does.

edit: I just changed your function signature a bit -- the first change is a matter of taste, replacing identifier[] by *identifier. I like to do this because this is what happens internally anyways, so it makes clearer what the function actually takes. The second one is adding a const where appropriate: Your function never changes what is pointed to by source, so you should make this explicit -- this way the compiler can catch more errors for you.




回答2:


Two things you need to keep in mind:

  • C uses pass-by-value.
  • You cannot change the address of an automatic array.

Now,

my_strcpy(target, source);

is the same as

my_strcpy(&target[0], &source[0]);

which passes the address of first element of both the arrays and

void my_strcpy(char target[], char source[])

is the same as

void my_strcpy(char* target, char* source)

where target points to the address of the first element of the array target in main and source points to the address of the first element of the array source in main.

So,

target = source;

simply changes the location where target points to. Now, both target and source points to the same memory location, i.e, to the address of the array source in main. This doesn't have any effect on either of the arrays in main as C uses pass-by-value. Both the pointers in the function have different addresses as that of the array.



来源:https://stackoverflow.com/questions/32547413/why-is-a-string-copy-function-just-assigning-the-pointer-not-working

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!