سؤال

I have:

typedef struct table {

int size;

} Table;

So I have a parameter for a method as:

Table **table

But when I do:

table->size = 5;

OR:

*table->size = 5;

It doesn't work and my flags is giving me the error: request for member 'size' in something not a structure or union

Please help.

هل كانت مفيدة؟

المحلول

To avoid all that weird indirection, it's easier to use a local variable and go:

void myfunc(Table ** my_table) {
    Table * ptable = *my_table;
    ptable->size = 5;

    /*  etc  */
}

but as others have pointed out, (*table)->size = 5 and the like will do the same thing.

If you need to modify what's being pointed to, then:

void myfunc(Table ** my_table) {
    Table * ptable = malloc(sizeof(*ptable));

    /*  Do stuff with new table, then update argument  */

    *my_table = ptable;
}

Here's an example of the latter:

#include <stdio.h>
#include <stdlib.h>

typedef struct table {
    int size;
} Table;

int create_table(Table ** table, int size) {
    Table * new_table = malloc(sizeof(*new_table));
    if ( new_table == NULL ) {
        return -1;
    }

    new_table->size = size;

    *table = new_table;
    return 0;
}

int main(void) {
    Table * my_table;

    if ( create_table(&my_table, 5) == -1 ) {
        fprintf(stderr, "Couldn't allocate memory for new table.\n");
        return EXIT_FAILURE;
    }

    printf("New table size is %d\n", my_table->size);

    free(my_table);

    return 0;
}

You could, of course, just have create_table() return a Table * to the newly created table, but in your case, that function has been declared as returning int. Could be for any number of reasons, but in the above I've just assumed it's to return an error code. As we know, a function in C can only return one value, so if it's returning an int it can't return a Table * as well, so the only way to get that new pointer is to modify an argument, and if you want to modify a Table *, you have to pass the address of that Table *, so your function must accept a Table **.

نصائح أخرى

The dereference operator (*) has a lower priority, so this:

*table->size

is evaluated as:

*(table->size)

Since table is a pointer to a pointer, and pointers can't have members, you get an error. What you need is:

(*table)->size = 5;

Now, *table is evaluated first, yielding a pointer to a Table. -> is then able to be applied to it.

Unrelated:

I noticed that you use different identifiers for the struct name and for its typedef. This isn't necessary. You can just use:

typedef struct Table {
    int size;
} Table;

if using table_t **mytable do (*mytable)->size = 5;

if using table_t *mytable do mytable->size = 5;

typedef struct /* table */ {
    int size;
} table_t;  //conventional naming

int main() {
    table_t *mytable = malloc((sizeof *mytable)); //avoid "Access Violation", by allocating memory
    mytable->size = 5; //set size to '5'
    return 0; //conventional return
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top