简体   繁体   中英

printf(“%d\n”, 1000000001) cause Segmentation fault?

I do not know why, gcc version 4.9.2 (Ubuntu 4.9.2-10ubuntu13 x86_64)

Breakpoint 1, convertToTitle (n=1000000001) at excel_sheet_column_title.c:14
14      printf("%d\n", n);
(gdb) n

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400697 in convertToTitle (n=1000000001) at excel_sheet_column_title.c:14
14      printf("%d\n", n);
(gdb) p n
$1 = 1000000001

The complete code of the function, just called the function with 1000000001 in the main function:

char *convertToTitle(int n)
{
    int mod, idx, last = n / 26 + 1;
    char str[last], *title, *tp;

    printf("%d\n", n);

    idx = last;
    while (n > 26) {
        mod = n % 26;
        if (mod > 0) {
            str[--idx] = mod - 1 + 'A';
        } else if (mod == 0) {
            str[--idx] = 'Z';
            n -= 1;
        }
        n /= 26;
    }
    if (n > 0) {
        str[--idx] = n - 1 + 'A';
    }

    title = (char *)malloc((last - idx + 1) * sizeof(char));
    tp = title;
    for (; idx < last; idx++) {
        *tp++ = str[idx];
    }
    *tp = '\0';

    return title;
}

Your last is very large. Move it outside of local function (or mark it static) to avoid segfault.

As an alternative (and correct) solution, calculate correct value of last.

(I think you wanted log 26 n + 1)

26 last >= n
last = log 26 n

last = ceil(log(n) / log(26)) + 1;

Weak calculation of needed buffer size for str[] resulted in an excessively large array size last of 1000000001/26 + 1 . This array size was unsupportable as coded as a local variable.

What is needed is a much smaller array about log26(n) .

There is little need to "right-size" the buffer per various values of int n . Simply use a constant size that works for INT_MAX .

As the bit size of an int is about log2(INT_MAX)+1 ,

#include <limits.h>
#define ABOUT_LOG2_26 4.7
#define BUF26_SIZE ((int)(sizeof(int)*CHAR_BIT/ABOUT_LOG2_26 + 2))

char *convertToTitle(int n) {
  char str[BUF26_SIZE];
  ...
  // Also cope with negative values of n
  if (n < 0) Handle_Error();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM