Nobilis
Nobilis

Reputation: 7458

In C why does my pointer argument change when I modify its contents?

I have this custom string copy function and I've noticed that the *dest argument changes upon dereferencing it and modifying its contents:

char *copyArray(char *dest, char *src)
{
    char *a = dest;

    while (*dest++ = *src++)
        ;   
    char *b = dest;

    if ( (a-b) != 0)  
        printf("Dest pointer has changed\n");

    return dest;                                                                        
}

And if you consider the following code:

int main()
{
    char name [] = "Hello, there!";

    char *new = copyArray(name, "bye");

    printf("New is '%s', name is '%s'\n", new, name); 

    return 0;
}

I get the following output:

Dest pointer has changed
New is 'o, there!', name is 'bye'

Why does this happen?

My intent was for *new to point to the same location name[] points to, but obviously as the address changed, it points to a different place.

I feel that what's happened is that once the copying ended, C moved the original contents of the destination string minus the number of characters changed (4 for "bye") to a new address and assigned that to *dest.

Is this what's really happening? And could somebody please explain to me why?

This is not really work related, I'm just trying to understand better how pointers behave.

Thank you very much for your replies!

Upvotes: 1

Views: 124

Answers (2)

hmjd
hmjd

Reputation: 122011

The argument dest is being incremented (in the while condition) four times (as "bye" is 4 characters including the null which will be assigned on the final iteration of the while) inside the function copyArray() and its value is then returned so new points to name + 4.

To have new point to the beginning of name return a from copyArray().

Upvotes: 4

fvu
fvu

Reputation: 32973

The problem occurs here

while (*dest++ = *src++)
    ;   

which in plain english means copy the thing pointed to by src into the thing pointed to by dest, and after that increment both src and dest (that is, advance both pointers to point to the next thing).

Use a copy of the pointer if you want to avoid changing it - eg the a variable you already created, and return that one.

Upvotes: 4

Related Questions