1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Wrong Output

Discussion in 'C' started by creative, Mar 26, 2010.

  1. creative

    creative New Member

    Joined:
    Feb 15, 2010
    Messages:
    87
    Likes Received:
    0
    Trophy Points:
    0
    Why does the following program not change the value of p after invoking the function 'st'?

    #include <iostream.h>
    #include <conio.h>
    void st(char * q)
    {
    q = "xyz";
    cout<<q;
    }
    void main()
    {
    char *p;
    p = "abc";
    st(p);
    cout<< '-' << p;
    }

    The output expected is : xyz-xyz
    but Actual output is : xyz-abc
     
  2. pankaj.sea

    pankaj.sea New Member

    Joined:
    Apr 6, 2009
    Messages:
    461
    Likes Received:
    13
    Trophy Points:
    0
    Occupation:
    Web Developer
    Location:
    Kolkata
    Home Page:
    What's happening is that function parameters are passed by value, not by reference.

    When you call the st function with p as a parameter, a copy of p is placed into q. So when you modify q in the st function, you change the copy, not the original.

    The fix is to pass a pointer to a pointer as a parameter to st,

    char **q

    Then when you want to change the value,

    *q = "abc";

    And when you call st:

    st(&p);
     
  3. creative

    creative New Member

    Joined:
    Feb 15, 2010
    Messages:
    87
    Likes Received:
    0
    Trophy Points:
    0
    Despite your accurate solution, I am still in confusion.

    Being declared as a pointer, 'p' is supposed to contain the address of the string "xyz".

    A String is called an array of characters and arrays are inherently passed by reference. So, when I pass 'p' [a pointer], it should pass the address of the string. How is it passing the value instead of the address of string? Why is not a case of Call by Reference?

    Sorry for bothering you too much?
     
  4. pankaj.sea

    pankaj.sea New Member

    Joined:
    Apr 6, 2009
    Messages:
    461
    Likes Received:
    13
    Trophy Points:
    0
    Occupation:
    Web Developer
    Location:
    Kolkata
    Home Page:
    Arrays are passed by value. The 'value' of an array is the address of it's first element. And in your main function, p is declared as a pointer to the array of 3 characters x, y, and z. When you call st, the value contained in the pointer p is passed to st. But not the address of the pointer p.

    Now you can tell C++ to pass parameters by reference. I didn't mention it before because I didn't really know if a reference to a pointer could be done. But I've found out that it does. I had to look it up and try it out. I've only tested on MS Visual Studio 2008. I can't say if other compilers support it (probably do). As far as I know, it will not work in a plain C compiler.

    Simply declare st as: void st ( char * &p)

    The rest of your program would remain as you originally wrote it.
     
  5. pankaj.sea

    pankaj.sea New Member

    Joined:
    Apr 6, 2009
    Messages:
    461
    Likes Received:
    13
    Trophy Points:
    0
    Occupation:
    Web Developer
    Location:
    Kolkata
    Home Page:
    But the simple point here is that in C++, all parameters are passed by value unless you tell the compiler to pass by reference by placing a '&' before the parameter name.

    If you pass by value and you make a change to the parameter, it does not affect the original variable passed as a parameter.
     
  6. creative

    creative New Member

    Joined:
    Feb 15, 2010
    Messages:
    87
    Likes Received:
    0
    Trophy Points:
    0
    Thank you very much for giving me liberty to ask my doubts.

    Pls see the following code. I have not passed the array through reference explicitly. But, still, it has got changed. Whereas in my earlier problem, there is no change. For me, both the cases are same. This confusion is driving me nuts.

    void TestOfReference(char str[])
    {
    strcpy(str,"C++ makes me mad.");
    cout << "After CHANGE INSIDE function : " << str << endl;
    }
    void main()
    {
    char str[]="C++ is hard to learn.";
    cout << "Original str = " << str << endl;
    TestOfReference(str);
    cout << "Back to Main = " << str << endl;
    }
     
  7. pankaj.sea

    pankaj.sea New Member

    Joined:
    Apr 6, 2009
    Messages:
    461
    Likes Received:
    13
    Trophy Points:
    0
    Occupation:
    Web Developer
    Location:
    Kolkata
    Home Page:
    In both programs you passed a char pointer to a function. The difference is what you tried to do with the pointer.

    In this case, you copied new characters to the same address.

    In your original code, you tried to change what the pointer pointed to.

    As a side note, it is fortunate that the string you copied in TestOfReference is shorter than the original data declared in main. If the new string had been longer, you would have a buffer overrun and all the problems that brings.

    It would be better to declare the original array and initialize it as follows:

    char str[100];
    strcpy( str, "C++ is hard to learn.");

    The array now has space to accept somewhat larger strings without a buffer overrun.
     
  8. creative

    creative New Member

    Joined:
    Feb 15, 2010
    Messages:
    87
    Likes Received:
    0
    Trophy Points:
    0
    I had deliberately kept the length of the string small to avoid the buffer overflow.

    Anyhow, now check out this example. The output is the same, even though I have manipulated the pointer.

    void TestOfReference(char *ptr)
    {
    ptr+=6;
    *++ptr='E';
    *++ptr='A';
    *++ptr='S';
    *++ptr='Y';
    cout << "After CHANGE INSIDE function : " << ptr << endl;
    }
    void main()
    {
    char str[]="C++ is hard to learn.";
    char *ptr=str;
    cout << "Original str = " << ptr << endl;
    TestOfReference(ptr);
    cout << "Back to Main after = " << ptr << endl;
    }
     
  9. pankaj.sea

    pankaj.sea New Member

    Joined:
    Apr 6, 2009
    Messages:
    461
    Likes Received:
    13
    Trophy Points:
    0
    Occupation:
    Web Developer
    Location:
    Kolkata
    Home Page:
    Yes, you modified the pointer in the TestOfReference function. But since you were still working in the same area of memory, the string got changed. But you will notice that though you changed the value of ptr in TestOfReference, the value in ptr in main did not change. ptr was passed to TestOfReference by value. The last line of output is 'Back to Main after = C++ is EASY to learn'.

    If ptr had been passed by reference, your program would have printed 'Back to Main after = to learn' as the last line of output.
     

Share This Page