Converting pid_t to string

Viewed 11712

I am trying to convert a pid into a string. I tried it this way:

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

I assume that my mistake is maybe that I have not added a NULL in the end. I tried to do that but still got error messages. Can someone explain me what is the best way to but a PID into a char * ("string") ? Thanks!!

4 Answers

sizeof(int) is most likely 4 bytes on your system. A string containing a PID will need (assuming a 16 bit PID) at least 6 bytes: 5 for decimal digits and 1 for the null terminator. So you're not allocating enough space and potentially writing past the end of the allocated array. This invokes undefined behavior.

Make sure you allocate enough space for the string in question:

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

Or use a fixed size string:

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

If your system supports 32 bit PIDs, you'll need at least 11 bytes. For 64 bit PIDs, at least 21.

The mypid character array is not of the correct size. You are using sizeof(int) which is the number of bytes necessary to hold an integer on your system, not the string length of the integer. You could either count the number of digits if you want to be exact, or allocate a buffer of sufficient size, if exact storage is not a concern.

Correct and safe would be:

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);

sprintf will format the string and add a terminating zero for you, given sufficient buffer space to do so.

Your actual problem is this: sizeof(int) is not sufficient to hold the string value of any possible integer; that's just the length of an int in bytes on your system. If an int is 32 bits on your system, you need to allocate at least 12 bytes to accommodate for the longest possible base-10 string representation (-2147483648 plus the terminating zero). If an int is 64 bits, you need to allocate 21 bytes.

to convert a pid into a string

malloc(sizeof(int) is the size of an int such as 4 bytes. It is not the amount of memory to save as a decimal text in a string.


getpid() returns type pid_t.

Given pid_t is signed per IEEE (it is buried deep) and here, but of unknown width, it is reasonable to assume it is no wider than intmax_t.

Assigning a pid_t to an int can result in loss of information.

The minimal allocation

Let asprintf() allocate and convert to a string. ref

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

  // use mypid somehow.

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