Alex Rivera | Logout

Using snprintf to avoid buffer overruns

Asked 2009-11-21T12:51:02.133
27

I am using snprintf like this to avoid a buffer overrun:

char err_msg[32] = {0};
snprintf(err_msg, sizeof(err_msg) - 1, "[ ST_ENGINE_FAILED ]");

I added the -1 to reserve space for the null terminator in case the string is more than 32 bytes long.

Am I correct in my thinking?

Platform:

  • GCC 4.4.1
  • C99
Edit
Report

2 Answers

42

As others have said, you do not need the -1 in this case. If the array is fixed size, I would use strncpy instead. It was made for copying strings - sprintf was made for doing difficult formatting. However, if the size of the array is unknown or you are trying to determine how much storage is necessary for a formatted string. This is what I really like about the Standard specified version of snprintf:

char* get_error_message(char const *msg) {
    int e = errno;
    size_t needed = snprintf(NULL, 0, "%s: %s (%d)", msg, strerror(e), e);
    char  *buffer = malloc(needed+1);
    if (buffer) sprintf(buffer, "%s: %s (%d)", msg, strerror(e), e);
    return buffer;
}

Combine this feature with va_copy and you can create very safe formatted string operations.  

answered 2009-11-21T13:30:44.740
-1

sizeof will return the number of bytes the datatype will use in memory, not the length of the string. E.g. sizeof(int) returns '4' bytes on a 32-bit system (well, depending on the implementation I guess). Since you use a constant in your array, you can happily pass that to the printf.

answered 2009-11-21T12:53:52.847

Your Answer