简体   繁体   中英

struct forward declaration in C

I want to hide a specified struct in my c module, so struct declaration is in the *.c file and the header contains a typedef. Something like this:

/* member.h */
typedef struct MEMBER_T *member_t;

/* member.c */
#include "member.h"
struct MEMBER_T {
    unsigned int member_id;
    char name;
};

and later in the c file I want to do a member table:

members = calloc(10, sizeof(member_t));

but it's wrong, I know. How can I use thie solution? I mean how can I create an object for member_t?

Thanks in advance!

You are allocating an array. you still need to allocate each of its elements.

If you want to hide the struct in .c file, than it would also be a good idea to encapsulate its creation. So the user of you struct will not ha to bother whether to user sizeof(member_t) or sizeof(*member_t) or sizeof(struct MEMBER_T) .

define a function membet_t* create_member_array(int) in you header in addition to typedef struct MEMBER_T* member_t .

implement it in you .c file

member_t* create_member_array(int length) {
    member_t* arr = (member_t*) malloc(length * sizeof(member_t));
    if(arr) {
        int i = 0;
        for(; i < length; i++) {
            arr[i] = (member_t) malloc(sizeof(struct MEMBER_T));
            if(arr[i]) {
                arr[i]->member_id = 0;
                arr[i]->name = NULL;
            }
        }
    }
    return arr;
}

the declaration in you struct char name; combined with the statement members[0]->name = "test" is not correct. You declar a single char and try to a ssign a string to it, witch itself is not correct. it should be char* name and you shold allocate mememory before trying to copy a string to ist using strcpy()

member[0]->name = malloc((strlen("test") + 1)  * sizeof(char)); // 1 more the terminating '\0' !
strcpy(member[0]->name, "test");

alternativ:

member[0]->name = strdup("test");

This is a lot of memory allocation witch you need to make sure you release / free it. You will have to create another function to free all this memory

void free_member_array(member_t* members, int length) {
    for(int i = 0; i < length; i++) {
        if(members[i]->name) {
            free(members[i]->name);
        }
        free(members[i]);
    }
    free(members);
}

使用sizeof(*member_t)sizeof(struct MEMBER_T)

If you've hidden the struct definition in a .c file, you can't use sizeof to find its type outside of that module.

The solution is to either expose an function in the module that does the allocation (and perhaps initialisation too), or to provide a function that gives the size.

Or of course, to move the definition back into the header file.

If you want to allocate 10 structs of type member_t you must allocate 10 times the size of the latter, in your code you are only allocating 10 time the size of a pointer:

/* member.h */
typedef struct MEMBER_T *member_t; //  here your typedef member_t is on a pointer

your second problem is that, if you want to use a char* in your structure, you must allocate what you want to put inside it, if the member name of your struct member_t is a char , in order to fill this char with "test" you have to allocate enough space.

/* member.h */
typedef struct MEMBER_T member_t;

/*file.c*/
member_t *members;
members = malloc(10 * (sizeof(member_t))); 
// here i allocate 10 structs of type member_t

members[0].name = strdup("test"); 
// here i allocate enough place for "test" by 
// using the strdup function who returns an allocate 
// element.

if your printf("%s\\n", members[0].name); you will receive "test\\n".

Like me and others have said, sizeof(member_t) is not the same as sizeof(struct MEMBER_T) . That's one of your problems.

The other which you explain in a comment is that you want the name member to be a string. The problem here is that you declare the member as a single character. Either declare it as a pointer to a character ( char *name ) or as an array ( char name[MAX_NAME_LENGTH] , with MAX_NAME_LENGTH something appropriate for you). In the first case I suggest you use strdup to copy the strings, but remember to free them when done. In the last case, use strncpy .

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