C语言用ADT隐藏结构体实现时出现不完整typedef无效使用错误如何解决?
错误产生原因
你采用ADT封装的核心是把结构体struct website的具体定义隐藏在website.c内部,仅在头文件website.h中对外暴露不完整类型声明typedef struct website WEBSITE;。
对于仅引入了website.h的主程序来说,编译器仅知道WEBSITE是一个结构体类型,但完全不知道该结构体的成员构成、占用内存大小,因此:
- 主程序中执行
sizeof(WEBSITE)时,编译器无法计算该类型的内存占用,直接抛出invalid application of ‘sizeof’ to incomplete type错误 - 主程序中对
WEBSITE*指针解引用赋值*site = website_create()时,编译器不知道结构体的内存布局,无法完成值拷贝操作,抛出invalid use of incomplete typedef ‘WEBSITE’错误
另外你当前的接口设计本身存在逻辑问题:website_create()返回WEBSITE值类型,而对外暴露的WEBSITE是不完整类型,调用方根本无法声明对应类型的变量接收返回值,也无法完成值拷贝。
解决方案
调整ADT接口设计,所有对不完整类型的操作都通过指针完成,内存分配、释放的逻辑全部封装在库内部,不要让调用方直接操作结构体内存。
1. 修改头文件website.h的函数声明
#ifndef WEBSITE_H // 补上遗漏的头文件守卫判断,避免重复引入报错 #define WEBSITE_H #include <stdio.h> #include <stdlib.h> typedef struct website WEBSITE; // create函数返回堆分配的WEBSITE指针,调用方不需要感知结构体大小 WEBSITE* website_create(void); void website_apagar(WEBSITE **website); #endif
2. 修改website.c中的函数实现
#include <stdio.h> #include "website.h" struct website{ char titulo[40]; char url[512]; }; WEBSITE* website_create(void){ // 内存分配逻辑放在库内部,此处编译器可见完整结构体定义,可以正常使用sizeof WEBSITE *site = malloc(sizeof(WEBSITE)); if (site == NULL) { return NULL; } // 限制读入长度避免缓冲区溢出 scanf("%39s", site->titulo); scanf("%511s", site->url); return site; } // 补充销毁函数的实现 void website_apagar(WEBSITE **website) { if (website == NULL || *website == NULL) { return; } free(*website); *website = NULL; }
3. 修改主函数调用逻辑
// 不需要自行malloc,直接调用封装好的create接口获取实例指针 WEBSITE *site = website_create(); if (site == NULL) { // 内存分配失败的异常处理逻辑 exit(1); } // 后续对site的操作全部通过库提供的接口完成,不要直接解引用site指针 // 使用完毕后调用销毁接口释放内存 website_apagar(&site);
内容的提问来源于stack exchange,提问作者luis2608
相关产品推荐
相关产品推荐

