简体   繁体   中英

Re: Struct Array with Varying Size Structs--Clarification

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM