简体   繁体   English

C中的结构前向声明

[英]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. 我想在我的c模块中隐藏指定的结构,因此结构声明在* .c文件中,并且标头包含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: 后来在c文件中我想做一个成员表:

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? 我的意思是如何为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. 如果要将结构隐藏在.c文件中,则将其创建封装起来也是一个好主意。 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) . 因此,您的struct用户将不必费心使用用户sizeof(member_t)sizeof(*member_t)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 . 除了typedef struct MEMBER_T* member_t之外,还要在标头中定义函数membet_t* create_member_array(int)

implement it in you .c file 在您的.c文件中实现

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; 您在结构体char name;的声明char name; combined with the statement members[0]->name = "test" is not correct. 与语句members[0]->name = "test"组合的语句不正确。 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() 它应该是char* name ,在尝试使用strcpy()将字符串复制到ist之前,您应先分配内存

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. 如果您将struct定义隐藏在.c文件中,则不能使用sizeof在该模块之外查找其类型。

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: 如果要分配10个类型为member_t的结构,则必须分配10倍的大小,在代码中,您只分配10倍于指针的大小:

/* 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. 第二个问题是,如果要在结构中使用char *,则必须分配要放入其中的内容,如果struct member_t的成员名称是char ,则用“ test” 填充此char “您必须分配足够的空间。

/* 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); 如果您的printf(“%s \\ n”,成员[0] .name); you will receive "test\\n". 您将收到“测试\\ n”。

Like me and others have said, sizeof(member_t) is not the same as sizeof(struct MEMBER_T) . 就像我和其他人所说的, sizeof(member_t)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. 您在注释中解释的另一个是您希望name成员是字符串。 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). 可以将其声明为指向字符的指针( char *name ),也可以声明为数组( char name[MAX_NAME_LENGTH] ,其中MAX_NAME_LENGTH适合您)。 In the first case I suggest you use strdup to copy the strings, but remember to free them when done. 在第一种情况下,我建议您使用strdup复制字符串,但是切记在完成后free它们。 In the last case, use strncpy . 在最后一种情况下,请使用strncpy

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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