2

I have a question regarding one of the solutions that was posted--the accepted one on this thread: https://stackoverflow.com/a/4982586/5854333 .

I would have left a comment on it instead of starting a new question thread, but I do not currently have the experience necessary. The program indeed runs as promised and is similar to what I intend to actually implement, but I'm still confused as to whether there may be subtle memory issues in it.

For example, in the portion:

void addStringToHolder(stringHolder * holder, const char * string) {
    char ** newStrings = realloc(holder->strings, newStringCount * sizeof(char *));
    if (newStrings != NULL) {
        holder->strings = newStrings;
    }
}

(we are working in this function with the struct)

typedef struct {
    int numberOfStrings;
    char ** strings;
}stringHolder;

Can the double pointer strings really be modified in this function? I thought we always had to pass in a pointer to the thing we wanted to modify, rather than the thing itself. Wouldn't we have to pass in a triple pointer if we wanted to modify the double pointer?

Of course we are also passing in a pointer to the struct in the first place, so does that make this work? I think I'm getting lost in all of these pointers. A little clarity would be helpful. Hopefully understanding this case will allow me to understand the others.

7
  • 2
    You are telling the function by passing the pointer to the structure: Hey, there is some stuff located in that place in memory, go there and make any mess you want. And it does. Commented Apr 20, 2016 at 15:32
  • Just to make sure, is your second parameter string of const char * supposed to be unused? It's being passed in, but I don't see any literal use of the variable string. Commented Apr 20, 2016 at 15:48
  • @EugeneSh. So passing in a pointer to the struct allows us to modify any of the structure's elements. That seems reasonable, thanks. Now, why would we pass in a double pointer to the struct, as in void createNewStringHolder(stringHolder ** holder) { (*holder) = malloc(sizeof(stringHolder)); } ? Presumably we are changing the size of the memory allocated to the struct, but didn't it already have this size from its definition when it was declared in the main function? What did this change? Commented Apr 20, 2016 at 15:49
  • @8protons I only added in the part of the function that I didn't understand in order to make my question more readable. You can see the fuller context in the link. Commented Apr 20, 2016 at 15:51
  • 1
    It's a double pointer, as it is intended to point to multiple strings. Each string is pointed by a single pointer, while the bunch of strings are pointed by a bunch of pointers, so you need a pointer to pointers. Commented Apr 20, 2016 at 15:52

1 Answer 1

1

Can the double pointer strings really be modified in this function?

Shortly, yes.

To elaborate:

A pointer in C is just a location in the memory, when you pass it to a function you simply tell the function where to preform its operation.

By passing in a pointer to the struct, we are calling all of its elements by reference, and thus we can modify any of its elements, including the double pointer strings.

Say we have a pointer to your struct stringHolder* h_ptr where:

typedef struct {
   int numberOfStrings;
   char ** strings;
}stringHolder;

Now using * to dereference the pointer(s) you can access every level:

h_ptr /*some adress in memory*/
*h_ptr /*the value stored in said adress (we know its a stringHolder)*/

using the syntax x->y instead of (*x).y for readability

h_ptr->numberOfStrings /*the integer value stored in this struct*/
h_ptr->strings /*a pointer to an array of C string pointers*/
*(h_ptr->strings) /*the first "string" in said array, same as saying
                    a pointer to the first char in the first "string"*/
**(h_ptr->strings) /*the first char of the first "string"*/

And with pointer arithmetic we can get wherever we want and modify the values (as long as we keep the C convention of null terminated strings)

*(h_ptr->strings + 1) /*the second "string" in strings array*/
*(*(h_ptr->strings + 2) + 4) /*the fifth char in the third "string"*/

and so on.

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

1 Comment

Thanks for the explanations! I think the key answer here is what Eugene Sh. pointed (hah!) out. By passing in a pointer to the struct, all contents of the struct can be modified. I understand how the pointers work in these examples--my main concern was that since we used realloc with the double pointer, the double pointer sometimes needs to change location, so I wanted to make sure it was indeed being called by reference rather than value, so that it could be modified if necessary. Eugene Sh. confirmed that it was, since we were passing in a pointer to the struct. Thanks again!

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.