Wednesday, January 5, 2011

a reminder about strings and local variables



I was pondering to myself about local variables and how to pass values out of functions to main or other functions. While pondering I realized I wasn't sure how to pass a string. So, I wrote this program to prove I could do it.

string_generator takes a pointer to a character array as an argument, which is good because this is a memory address that won't get blown away once the function ends. While inside the function we pass some characters to the memory address. Here's where I get confused - it's one of those times where I know it's right but I don't know why it worked. I don't understand why I NEED to return the pointer back to itself (return str;).

To illustrate the point I'll add more code.



Here I have another function string_generator2. Again, I pass it the address of a string and pass characters to that address. When I try to print it out in the second printf I just get "(". I don't understand... isn't passing data to a memory address enough?

I kind of understand why the first function works. Printf wants a pointer to a character array and that's what the string_generator function delivers.

I thought that string2 was getting altered by string_generator2, but it doesn't seem to be.

1 comment:

  1. This is kinda tricky.

    The catch is that you are passing "a pointer to the first element in the array of characters defined by 'string2' " BY VALUE. Hence, the pointer 'str' becomes a local variable to the function 'string_generator2()'.

    Thus, when the following assignment is made:

    str = "printme2\0";

    The pointer 'str' (which is really just shorthand for &str[0]) now contains "the address of the first character in the literal string 'printme\0'". But because 'str' is local to 'string_generator2()', it is destroyed when the function returns.

    This is subtly different from what (I believe) you want to accomplish, which is passing a reference to the string object, or a "reference to the reference of the first character in an array of characters".

    Doing so requires the following syntax:

    void string_generator2(char *str[])
    {
    *str = "printme\0";
    }

    /* .... main .... */

    string_generator2(&string2);

    This passes the string pointer by reference, allowing you to modify the pointer itself and not just the data pointed to by the pointer.

    To phrase it another way: you have a pointer (string2 == &string2[0]) that you want to pass to a function by reference. Therefore, the argument to the function must be a "pointer to a pointer". You could also use the 'char **str' syntax, but I believe that 'char *str[]' is the "preferred nomenclature, man".

    FWIW, the garbage that you get when you print 'string2' is just its uninitialized contents. Try initializing the strings in your original program to prove to yourself that they never change.

    ReplyDelete