views:

83

answers:

3

Hey guys I'm trying to figure how pointers are returned by strcat(), so I tried implementing my own strcat() to see how it works. The following is my code for mystrcat(), which works like the real strcat():

char *mystrcat(char *destination, char *source)
{
    char *str = destination;

    while (*str != '\0')
    {
        str++;
    }

    while (*source != '\0')
    {
        *str = *source;
        str++;
        source++;
    }
    *str = '\0';

    return str;
}

So let's say in my main(), I have

char string[BUFSIZ];
mystrcat(string, "hello");
printf("%s\n", string);

The output would be

hello

as expected. What I don't get is how returning the address of the local variable, str, would magically make the variable, string, point to it and also why is the variable, str, not deleted when the function terminates.

+1  A: 

You're not returning the address of the local variable. You're returning the value of the local variable. Since the variable in question is a pointer, its value happens to be an address. The address that is contained in the str variable points into the memory block provided by the argument destination.

What you seem to be misunderstanding is that this:

char* str = destination;

Does not create a copy of the destination string. It creates a pointer called str that points at the same memory location that destination points to. When you use str to manipulate the characters in that memory block, the string represented by destination is also modified, because str and destination point into the exact same string of characters in memory. That's how it "magically updates" the parameter.

Tyler McHenry
I think I more or less got it. However just to clarify, is it possible for me to just modify my "destination" parameter directly without creating a new pointer, and thus not needing to return anything?
jon2512chua
Short answer: Yes, you can modify `destination` directly. Long answer: The standard implementation of `strcat` returns a pointer to the beginning of the destination string (for convenience, more than anything). So really what you want to do to conform to that standard is to continue to do what you are already doing with `str`, but to `return destination;` instead of `return str;`. The reason is that the pointer that you use to do the manipulations will be pointing to the *end* of the string when you're done, and `strcat` should return a pointer to the *beginning*.
Tyler McHenry
Sorry but I don't really get what you mean by "for convenience". Correct me if I'm wrong, but seeing that "str" will be terminated at the end, thus leaving the only pointer to the string to be "destination", which points to the beginning of the string as it's been left untouched all this while, wouldn't it be a little pointless to return the pointer again? p.s. What's the tag to indicate that a word is a code?
jon2512chua
Having strcat() return a pointer to the start of the string allows one to do something like fopen(strcat(prefix, name), "r"). It also allows one to (inefficiently) strcat(strcat(string1,string2),string3); I agree it would probably have been more useful for strcat to return a pointer to the stored zero terminator, but enough code relies upon its present behavior that anything else would represent a breaking change. That having been said, I would think a _strcat_ex function (which behaved like strcat except for the above behavior) would be a nice addition to the standard library.
supercat
Convenience for the use of the function, not the implementation of it. Returning the pointer again allows a user to write something like `return strcat(foo, bar);` rather than having to write `strcat(foo, bar); return foo;`. And the inline code formatting is done by enclosing with backticks. See: http://stackoverflow.com/editing-help
Tyler McHenry
Alright got it thanks!
jon2512chua
A: 

str is a pointer to the string you pass in (destination), so you are modifying your original variable string from within your strcat function.

The pointer str does get deleted at the end of the routine, but it is not needed anymore.

BTW, it is confusing to use the word "string" as the name of a variable, because many languages reserve string as a keyword.

bde
Lol yeah I realised that. It's just that both my main() and mystrcat() functions used str so I changed one of it to string so there won't be any confusion.
jon2512chua
Normally it's not considered confusing to use the same variable name in two different functions. It's when you have the same variable name in two scopes that can be active at the same time (e.g. a global called `str` and a function local variable called `str`) that things get confusing.
Tyler McHenry
A: 

The first line of the function, you're assigning *str to be the same as *destination. In effect, when you return, you're returning *destination, which is the same as *str.

No memory is allocated, so no memory must be deleted.

Sam T.