1

I am presently new to programming and am following the C language which is being taught to us in our College. I have doubt in the actual functioning of the strcpy() function under the header-file #include<strings.h>

The general use of this function is given below -

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
     char a[] = "google";
     char *b = (char*)malloc((strlen(a) +1)*sizeof(char));
     strcpy(b,a);
     printf("%s, %s\n", a, b); //prints google, google
     free(b);   
}

We are given the following format and prototype of the same :

char *strcpy( char *to, const char *from)
{
    char *temp = to;
    while (*to++ = *from++);
    return temp;
}

I have a couple of doubts about this-

  1. What is an extra pointer ( temp ) requirement in the function? Can't we just return to; at the end of the function?

  2. I convinced myself that the temp variable is used because during each while loop, the pointer to is changing itself. That is first *to will be assigned *from and then to = to +1, and from = from +1, will take place which will result in changing the address stored in the pointer to. But if this is true, then what about the pointer from? Will, it also not change at the end of the strcpy() function?

  3. Where is the function returning the address stored in temp? ( the function should only work if b = strcpy(b,a); be mentioned not only strcpy(b,a);)

To check the given function I also made my own function "strcpy_me" and used it with the same format and prototype, and it gave the same results.

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

char *strcpy_me( char *to, const char *from)
{
    char *temp = to;
    while (*to++ = *from++);
    return temp;
}

int main()
{
     char a[] = "google";
     char *b = (char*)malloc((strlen(a) +1)*sizeof(char));
     strcpy_me(b,a);
     printf("%s, %s\n", a, b); // prints google, google
     free(b);   
}

Please help me clarify my doubt.

granthium
  • 111
  • 1
  • 4
  • 1) `to` changed value within the function; you can return the changed value... but the calling function has no use for it. 2) Correct. the **local** pointer `from` will change inside the function: no other variable outside changes. 3) Returning `temp` allows you to do `strcpy(foo, strcpy(bar, "quux"));` 4) Is there a question? – pmg May 24 '21 at 11:53
  • 1. The reason given in second point is correct. 2. What about the `from` pointer? It does change but why is that a problem? 3. The return value is stored wherever you choose to store it to. It's not clear what you are asking there. – kaylum May 24 '21 at 11:54
  • @pmg `from` is not only a local pointer. It's the address of the string a. I believe that as we call this function by reference ( and not by value ), at the end our char *a would be pointing to NULL and not the first char of "google". So while printing `a` in the `main` function, should have given nothing, instead of printing 'google' back. Please correct me if I am wrong. – granthium May 24 '21 at 12:12
  • `sizeof(char)` is 1 by definition, and in C returning from `malloc()` doesn't need a cast – Jack May 24 '21 at 12:36
  • Aside: cast not needed. Size to the referenced object. `char *b = (char*)malloc((strlen(a) +1)*sizeof(char));` --> `char *b = malloc(sizeof *b * (strlen(a) +1));` – chux - Reinstate Monica May 24 '21 at 13:26
  • @granthium: C has no concept of "call by reference". `from` is a local variable (a local pointer). Changes to `from` (to the pointer) inside the function do not change any variable outside the function... changes to `*from` (to whatever `from` currently points to) may change outside objects. – pmg May 24 '21 at 14:12

2 Answers2

2
  1. see 2

  2. It's a requirement from the implementation of strcpy to return a pointer to the beginning of the destination string. So if you want to implement your function in the same way as strcpy, you'll have to save a copy of the original pointer passed as parameter, in case you intend to change that parameter inside the function. This isn't a particularly useful or rational feature, but strcpy has been like that since the dawn of time.

  3. Not sure what you mean; here obviously: return temp;

  4. return to; is wrong. You have to realize that the function returns a value whether that value is used by the caller or not. Strict compilers might warn "value from function isn't used" in which case you'd have to write (void) strcpy(a,b); to silence it. Since your example doesn't use the returned value, it doesn't matter that it is wrong.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 2. ok I get your point 3. I meant that the function is just returning the address of the destination string, but it's not stored anywhere. I believe that the char * which is returned should be stored as `b = strcpy(b, a);` rather than just commanding `strcpy(b, a);` 4.Yeah I am sorry, I corrected that. I had used that to see what would happen in this case `return to;`. – granthium May 24 '21 at 12:20
  • @granthium The destination string is `b` itself. Doing `b = b` isn't necessary. You just need to execute `strcpy(b, a)`. – Shambhav May 24 '21 at 12:22
  • @granthium You can ignore the return value of `strcpy` since you know what it will return anyway. I believe the reason for it is to allow chaining of function calls like `strcat(strcpy(dest, "foo"), "bar")` which was probably considered reasonable programming style back in the 1970s. – Ian Abbott May 24 '21 at 13:59
-1
  1. What you think in no. 2 is correct.

  2. from does get changed but we don't need the previous value of from. to was stored in temp as to's original value should be returned, so we need it but no need for from.

  3. No, you don't need to do that. You can ignore return values in C(in most cases without warnings as well). No returning works as doing *to = *from changes the parameter's memory as well, in this case, b. So, *to = *from changes the array b directly. It is because to and b store the same memory.

Note: In your while loop, it's *to++ = *from++. It uses post addition, which for simplification, I didn't include here but all it does is increment both to and from after the operation.

  1. As I said in 3, you don't need the return value. In fact, because original to and temp point to the same memory as b, the function returns b itself. doing, b = strcpy_me(b, a) is the same as:

     strcpy(b, a);
     b = b; //b's value stays the same
    

And yes, return temp; is absolutely garbage in my opinion. It only causes confusion.

Shambhav
  • 813
  • 7
  • 20