5

I'm currently learning about strings, pointers and arrays in C. I tried to write a program where an array holds three pointers to string addresses. It all seems to work but the program behaves strangely.

Here's the code:

char** getUserDetails()
    {

    char* host = "localhost";

    char* username = "root";

    char* password = "mypassword";

    // create array for holding pointers to strings

    char *userDetailsHolder[3];

    userDetailsHolder[0] = malloc(sizeof(char)*strlen(host));   
    strcpy(userDetailsHolder[0], host);

    userDetailsHolder[1] = malloc(sizeof(char)*strlen(username));
    strcpy(userDetailsHolder[1], username);

        userDetailsHolder[2] = malloc(sizeof(char)*strlen(password));
        strcpy(userDetailsHolder[2], password);

        return userDetailsHolder;
    }

    int main()
    {

    char** userDetails = getUserDetails();

    printf("Host: %s\nUsername: %s\nPassword: %s\n", userDetails[0], userDetails[1], userDetails[2]);

    printf("Host: %s\nUsername: %s\nPassword: %s\n", userDetails[0], userDetails[1], userDetails[2]);

            return 0;
    }

Output: The output indicates that something went terribly wrong

Host: localhost
Username: root
Password: mypassword
Host: root
Username: localhost
Password: Host: %s
Username: %s
Password: %s

The first printf seems to work, but the second has the wrong data in it. What did I do wrong?

2 Answers 2

8

The problem is that you are returning a pointer to an array which resides on the stack. userDetailsHolder is allocated on the stack and is not available after the function returns.

You could use malloc once more to allocate the array itself, and then it will be available after the function returns.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks that makes sense. I have never done that though. I tried to add the following code:
char** arrayOnStack = malloc(sizeof(userDetailsHolder)); arrayOnStack = userDetailsHolder; return arrayOnStack;
The new code would be char **userDetailsHolder = malloc(sizeof(char *) * 3)
Hey thanks, works perfectly. Is there some kind of rule you use to keep track of all the de-referencing? As a beginner I find it quite confusing to know at which level I'm at..
It's quite simple when you get it... Every asterisk in the declaration of a pointer corresponds to one dereferencing. For example, if you have declared an int *****a, the expression **a will yield a pointer of type int ***.
|
3

Also, remember to allocate strlen(s)+1 bytes for strings. C strings are terminated with the zero byte and you need to make sure there's space for it.

1 Comment

Thanks, I already added it to the code: userDetailsHolder[0] = malloc(sizeof(char)*(strlen(host)+1));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.