将pid_t转换为字符串

5

我正在尝试将一个进程ID转换为字符串。我用了以下方法:

int pid = getpid(); //this int conversion should be ok as far as I know
char * mypid = (char *)malloc(sizeof(int));
sprintf(mypid, "%d", pid);

我猜我的错误可能是没有在末尾添加NULL。我尝试过这样做,但仍然收到错误消息。有人可以解释一下把PID放入char *(“字符串”)的最佳方法是什么吗?谢谢!!


5
为什么是 sizeof(int) - melpomene
2
"仍然有错误信息" - 什么错误信息? - melpomene
@melpomene "段错误" 可能是吗? - Andy Brown
不要对 malloc() 等函数的结果进行强制类型转换 - 这是不必要的,而且还可能隐藏缺少正确原型的错误。 - mlp
4个回答

7
您的系统上,sizeof(int) 很可能是4个字节。包含PID的字符串(假设PID是16位)至少需要6个字节:5个字符用于十进制数字,1个字符用于空终止符。因此,您没有分配足够的空间,有可能会写入到分配数组的末尾之后。这将导致未定义行为

请确保为所涉及的字符串分配足够的空间:

int pid = getpid();
char * mypid = malloc(6);   // ex. 34567
sprintf(mypid, "%d", pid);

或者使用固定大小的字符串:

int pid = getpid();
char mypid[6];   // ex. 34567
sprintf(mypid, "%d", pid);

如果您的系统支持32位PID,则需要至少11个字节。对于64位PID,至少需要21个字节。

1
你假设PID被限制在16位。 - melpomene
@melpomene 正确,尽管我不知道有任何具有更大PID的系统。 - dbush
1
根据 POSIX sys/types.hpid_t 可以和 long 一样大: "实现应支持一个或多个编程环境,其中 blksize_tpid_tsize_tssize_tsuseconds_t 的宽度不大于类型 long 的宽度。" - Andrew Henle
@melpomene 很好知道。已更新以反映。 - dbush

3

sprintf将会为您格式化字符串并添加一个终止零,只要有足够的缓冲区空间。

你的实际问题是这样的:sizeof(int)大小不足以容纳任何可能的整数字符串值;那只是你系统上int的字节数长度。如果在你的系统上int是32位的,那么你需要分配至少12个字节来容纳最长的十进制字符串表示(-2147483648加上终止零)。如果int是64位的,你需要分配21个字节。


1
尽管如此,您可能可以忽略字符串中存在负号的可能性。 严格来说,根据POSIX,这是不正确的(http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html)。 “blksize_tpid_tssize_t`应为有符号整数类型。” 我同意这很可能是安全的,因为我从未见过任何创建负PID的实现。 - Andrew Henle

3

mypid 字符数组的大小不正确。你正在使用 sizeof(int),它是在你的系统上保存一个整数所需的字节数,而不是整数的字符串长度。如果您想要精确计算数字的数量,可以计算数字的位数,或者如果确切的存储不是问题,则分配足够大小的缓冲区。

正确且安全的方法是:

const size_t max_pid_len = 12; // Could be system dependent.
int pid = getpid();
char * mypid = malloc(max_pid_len + 1);
snprintf(mypid, max_pid_len, "%d", pid);

3

将pid转换为字符串

malloc(sizeof(int) 的大小是一个 int,例如4个字节。这不是保存十进制文本为字符串所需的内存量。


getpid()返回类型为pid_t

根据IEEE(它深藏不露)和这里,给定的pid_t是带符号的,但未知宽度,合理的假设是它不会比intmax_t更宽。

pid_t分配给int可能导致信息丢失。

最小的分配

asprintf()进行分配并转换为字符串。参考

pid_t pid = getpid();
char *mypid = NULL;
if (asprintf(&mypid, "%jd", (intmax_t) pid) != -1) {
  // Success

  // use mypid somehow.

  free(mypid); // cleanup when done.
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接