-2

Have written a routine to swap strings , the first routine fails where as the second routine correctly swaps . Need to know the reason for the same they seem to do the same thing not sure why the second one works perfectly not the first .

First Method

void swap(char *str1, char *str2)
{
  char *temp = str1;
  str1 = str2;
  str2 = temp;
}

Second Method

void swap(char **str1, char **str2)
{
  char *temp = *str1;
  *str1 = *str2;
  *str2 = temp;
}
Santhosh Pai
  • 2,535
  • 8
  • 28
  • 49
  • 3
    C is pass by value. You want to read about the *Dereferencing*-operator. – alk Apr 18 '16 at 13:33
  • Another approach would be to compile the two snippets and then debug the code using a debugger stepping through the code inspecting all relevant variables to the what is *really* going on. – alk Apr 18 '16 at 13:35
  • @alk : that would crash for sure – Santhosh Pai Apr 18 '16 at 13:42
  • @alk Might be a bad example since string literal "hello" isn't of type `char**`. Creating local pointers to string literals and then swapping them of course works fine. However writing to data/read only segment won't work which I guess is what you're really after :) – Jite Apr 18 '16 at 13:47
  • Why there's a downvote for the question ? – Santhosh Pai Apr 18 '16 at 13:48
  • @SanthoshPai I guess because it's been asked numerous times before and they probably thought you should use the search function first hehe. – Jite Apr 18 '16 at 13:50
  • @Jite: Hu, temp brain lapse .. yes. thank you. Cleaning up ... – alk Apr 18 '16 at 14:01
  • In a programming language special symbols like `*` are not just for decoration, but have a meaning. Why do you expect `*` to have the same implications like `*`? (Note: I don't talk about comments!) – too honest for this site Apr 18 '16 at 14:10

2 Answers2

5

Short answer: The first function gets copies of the pointers and you just modify these copies, not what the original pointer actually points too.

Longer: The second function takes gets pointer-to-pointer "copies" that which in turn (presumably) containts the addresses to the original location of your real pointers. In that function you change what the original pointers point to.

If we compare a pointer to an int, an int variable has an address in memory, and the value at that memory address is the number that the int contains. int a = 4, a has an adress at which the number 4 is stored. Same goes for pointers. A pointer say char *b = "cde", b has an address where it's value is stored. A pointer contains the "value" that is another address, in this case the address to where the string "cde" is stored.

So what happens in your first function is that you send the value of str1 or str2, not the address to str1/str2 themselves. If you send the address of str1/str2 as in the second example, you are sending a pointer-to-pointer (char**) and it will work.

Jite
  • 4,250
  • 1
  • 17
  • 18
3

The parameters you pass to a function are always passed by value in C, which means changes you make to the parameters themselves in the function aren't reflected outside the function. In the first method, changing str2 inside the function doesn't change str2 outside the function. In the second method, with **str2, the extra * is actually reaching outside the function to change what str2 points to (and the same for str1). Therefore, the changes are visible outside the function.

cxw
  • 16,685
  • 2
  • 45
  • 81