如何打印utmp.h中utmp结构体数据并解决ut_id打印告警问题
告警原因
struct utmp中的ut_id字段被标记了nonstring属性,它是固定长度为4的字符数组,但不保证以'\0'结尾。C标准中printf的%s占位符要求传入的参数必须是合法的以空字符终止的C字符串,直接传入ut_id会导致函数可能越界读取数组后的内存,因此编译器会抛出溢出告警。
修复方案
方案1:使用printf精度限制(最简单)
由于ut_id固定长度为4,直接用%.4s占位符指定最大读取长度即可,无需修改其他逻辑:
printf("%.4s\n" , data->ut_id);
该写法会强制printf最多读取4个字符,即使ut_id没有末尾的空终止符也不会发生越界读。
方案2:手动构造合法C字符串
如果后续需要多次使用该字段的值,可以拷贝到临时缓冲区并手动添加终止符:
char id_buf[sizeof(data->ut_id) + 1]; memcpy(id_buf, data->ut_id, sizeof(data->ut_id)); id_buf[sizeof(data->ut_id)] = '\0'; printf("%s\n", id_buf);
完整修复后的参考代码
另外建议调用完getutent遍历结束后,调用endutent()关闭utmp相关的文件描述符:
#include <stdio.h> #include <utmp.h> #include <string.h> int main() { struct utmp *data; int i = 0 ; // 重置读取偏移到utmp文件开头 setutent(); data = getutent(); while(data != NULL) { ++i; // 用精度限制的方式打印 printf("%.4s\n" , data->ut_id); data = getutent(); } printf("总记录数:%d\n" , i); // 关闭打开的utmp文件 endutent(); return 0 ; }
内容的提问来源于stack exchange,提问作者Alex Lazar
相关产品推荐
相关产品推荐

