C语言中如何通过指针获取函数返回的结构体指针数组大小?
问题分析与解决方案
首先你用sizeof(**users)/sizeof(*users)的思路完全错误,原因如下:
sizeof(**users)计算的是单个User结构体的大小:你的User结构体包含两个20字节的char数组(共40字节),加上两个4字节的int(共8字节),总大小固定为48字节,这个值和数组内的用户数量毫无关系。sizeof(*users)计算的是单个User*指针的大小:ESP32-S3在64位编译环境下指针大小为8字节,同样是固定值。- 两者相除得到的
48/8=6,和你实际的7个用户没有关联,自然无法正确遍历。
另外你代码里还有两个明显错误:
- 循环条件用了
<=,会导致越界访问数组的第MAX_USERS个元素(数组下标从0开始,正确应该用<)。 - 判断
users[i]->user_name != NULL完全无效:user_name是char数组,不是指针,数组名会隐式转换为指向第一个元素的指针,永远不可能为NULL,这个判断根本筛不掉空的数组元素。
可行解决方案
方案1:新增获取数组容量的函数
在定义users_storage的模块里新增一个函数,直接返回数组总容量:
// 原模块中新增 int getUsersCapacity() { return MAX_USERS; }
调用方遍历代码:
struct User** users = getUsers(); int capacity = getUsersCapacity(); for (int i = 0; i < capacity; i++) { if (users[i] != NULL) { // 正确判断指针是否有效 printf("user_name=%s, index=%d\n", users[i]->user_name, users[i]->index); } }
方案2:用哨兵值标记数组末尾
初始化users_storage时将所有元素设为NULL,添加用户时只给前面的位置赋值,遍历到NULL就停止,无需知道数组总大小:
// 模块初始化函数中 memset(users_storage, 0, sizeof(users_storage)); // 调用方遍历代码 struct User** users = getUsers(); for (int i = 0; users[i] != NULL; i++) { printf("user_name=%s, index=%d\n", users[i]->user_name, users[i]->index); }
这个方案更灵活,能自动停止在有效用户的末尾,不会做无意义的循环。
方案3:将MAX_USERS暴露给调用方
把MAX_USERS定义在公共头文件中,让调用方通过包含头文件直接使用MAX_USERS,这也是C语言中常见的做法。
内容的提问来源于stack exchange,提问作者user1045680
相关产品推荐
相关产品推荐

