简体   繁体   中英

To swap two strings in C

This is a common method to swap two strings as below and it works pretty well,

void swap1(char **str1_ptr, char **str2_ptr)
{
    char *temp = *str1_ptr;
    *str1_ptr = *str2_ptr;
    *str2_ptr = temp;
}

int main()
{
    char *str1 = "John";
    char *str2 = "Mary";
    printf("Before: str1 is %s(%lp), str2 is %s(%lp)\n", str1, &str1, str2, &str2);
    swap1(&str1, &str2);
    printf("After: str1 is %s(%lp), str2 is %s(%lp)\n", str1, &str1, str2, &str2);
    return 0;
}

The output is:

Before: str1 is John(0x7fff68025bb8), str2 is Mary(0x7fff68025bb0)
After: str1 is Mary(0x7fff68025bb8), str2 is John(0x7fff68025bb0)

Aren't str1 and str2 pointing to read-only data segment memory? But the values they point at are all changed in the end? Where do I get wrong?

Aren't str1 and str2 pointing to read-only data segment memory?

Technically, it's simply undefined behaviour to try and change string literals. They may be read-only but it's not guaranteed.

But the values they point at are all changed in the end?

No. The only values that are changed are pointers to the strings, not the strings themselves.

Think of it this way, this is your initial state:

Variable  PointsTo  Address With Data ...
str1        ->      0x1000:      | J | o | h | n | \0 |
str2        ->      0x1100:      | M | a | r | y | \0 |
 |                               \____The strings_____/
 +- The pointers to the strings.

When you swap the pointer values, you end up with:

Variable  PointsTo  Address With Data ...
str2        ->      0x1000:      | J | o | h | n | \0 |
str1        ->      0x1100:      | M | a | r | y | \0 |

Note that the string literals have not changed at all (the exact same content exists at the exact same memory locations). The pointer values have changed but they're not subject to the same restrictions as the string literals.

This doesn't swap strings. A string is an array of characters. This swaps pointers. Pointers are not arrays and not strings. Pointers may point (in)to strings. In general it is not possible to swap strings.

For both strings you print (1) the string itself and (2) the address of a pointer to a string. This latter value is not particularly interesting, as there may be many pointers that point to the same string. A more interesting quantity is the address of the string itself. You can print it like that:

 printf ("The string is %s (%p)", s, s);

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