You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

getpwnam函数异常行为排查:为何打印用户名重复?

问题分析:getpwnam调用引发的字符串输出异常

代码示例

#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
        printf("%s %s\n", getpwnam("steve")->pw_name, getpwnam("root")->pw_name);
        printf("%d %d\n", getpwnam("steve")->pw_uid, getpwnam("root")->pw_uid);

        return EXIT_SUCCESS;
}

编译运行结果

$ gcc main.c && ./a.out
steve steve
1000 0

异常现象

第8行代码尝试打印用户steve和root的用户名,却两次输出steve;第9行打印二者的UID,却能正常输出1000和0。

根本原因解析

1. getpwnam的静态内存特性

getpwnam函数返回的指针指向静态分配的内存区域,结构体中的pw_name字段同样指向该静态内存中的字符串。每次调用getpwnam时,新的用户信息会覆盖这块静态内存的内容。

2. C语言函数参数的求值顺序

C语言标准未规定函数参数的求值顺序,多数编译器(如GCC)默认采用从右到左的求值顺序。

针对第8行的printf调用:

  • 编译器先求值右侧的getpwnam("root")->pw_name:此时静态内存中存储root的信息,pw_name指向字符串root;
  • 接着求值左侧的getpwnam("steve")->pw_name:静态内存被steve的信息覆盖,pw_name指向字符串steve;
  • 最后printf读取两个pw_name指针,但这两个指针指向的是同一块被覆盖后的静态内存,因此两次输出都是steve。

而第9行的UID输出正常,原因在于pw_uid是整数类型:

  • 不管参数求值顺序如何,每次调用getpwnam时,都会将当前静态内存中的pw_uid数值取出并压入栈中;
  • 后续调用覆盖静态内存的UID值时,栈中已经保存了之前的数值,因此printf能正确输出两个不同的UID。

补充说明:这是《Linux编程接口》习题8-1,原书问题存在错误,可查看官方修订版本。


内容的提问来源于stack exchange,提问作者Steve Lau

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 14:18:25