简体   繁体   中英

Understanding strings and arrays

Consider this code.

int main()
{
    char *s, *t;

    s = malloc(4 * sizeof(char));
    strcpy(s, "foo");
    t = s;
    printf("%s %s\n", s, t);         // Output --> foo foo
    strcpy(s, "bar"); // s = "bar"
    printf("%s %s\n", s, t);         // Output --> bar bar
}

There are 2 strings s and t . First I set s to "foo" and then make t point to s . When I print the strings, I get foo foo .

Then, copy "bar" to s and print again, I get bar bar .

Why does value of t changes in this case? (I copied "bar" to s why did t change).


Now when I change strcpy(s, "bar") to s = "bar" -

int main()
{
    char *s, *t;

    s = malloc(4 * sizeof(char));
    strcpy(s, "foo");
    t = s;
    printf("%s %s\n", s, t); // Output --> foo foo
    s = "bar"
    printf("%s %s\n", s, t); // Output --> bar foo
}

This code gives me foo foo and bar foo .

Why didn't it change in this case?

This is undefined behaviour , which means anything can happen:

char *s, *t;
strcpy(s, "foo");

as strcpy() is writing to a random location in memory because s is an uninitialised pointer.


( after edit that corrected undefined behaviour )

Question 1 - Why does value of t changes in this case? (I copied "bar" to s why did t change).

This is a pointer assignment:

t = s;

and results in both t and s pointing to the same memory that was malloc() and assigned to s earlier. Any change to that memory is visible via both t and s .

Question 2 - Why isn't t changing in the second case?

This assigns the address of the string literal "bar" to s :

s = "bar";

so now t and s do not point to the same memory location. t points to the memory that was earlier malloc() and assigned to s (because of the t = s; pointer assignment).

strcpy() and = are very different:

  • strcpy() copies characters to the memory address specified by its first argument
  • assignment, = , changes the address which a pointer holds
strcpy(s, "foo");

Copies foo to memory location pointed to by s t = s; Now, t and s both point to same location Hence, same output

Now, you copy bar to s . Since both t and s point to same location. Hence, same output again.


Upto this line everything is same

s = "bar"

You create a string constant bar . And assign its address to s . Its a pointer it can point to any memory location. not necessarily the original one.

Now,

s points to bar and t still to the earlier location it pointed to in the beginning and hence the output

a simplistic way to understand could be as follows :-

      s = malloc(4 * sizeof(char));    // this will be interpreted as follows 
      s = 123 ------------>|   |   |   |   | //some garbage values at these location
                           123  124 125 126   // some random address chosen.

      strcpy(s, "foo") ; // it copies at the address provided by s i.e.
                             |'f'|'o'|'o'|'\0'|
                              123 124 125  126 

      t = s;      this statement means t it pointing to address = 123

      strcpy(s, "bar"); // this statement copies at given address it means it will   override previous value .   i.e
                            |'b'|'a'|'r'|'\0'|
                             123 124 125 126

now t still pointing to address 123 that is why t, s both prints bar .

       s = "bar"  // this will  assign a new address to s which is base address of "bar" string . i.e .          
                           |'b'|'a'|'r'|'\0'|
                            321 322 323 324     

now s will contain address 321 while t has value 123 that is why s and t are giving different values .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM