Root21 Root21 - 2 months ago 15
C Question

Segmentation Fault in while loop (C)

I'm writing a program to convert base-10 numbers into their equivalents in other bases, but I keep getting a segmentation fault when I try to run it.

This is the code so far:

#include <stdio.h>

int base;
int num;
char* num2[50];
int x =0;

int main(){

printf("Input a number in base 10 and a base (2-16) that you would like to convert to in this format: 100 2\n");
fflush(stdout);
scanf("%d%d",&num, &base);
printf("%d%d", num, base); fflush(stdout);

while ((num % base) > 1){
printf("%d", x); fflush(stdout);
if(num % base == 10)
num2[x] = "A";
else if (num % base == 11)
num2[x] = "B";
else if (num % base == 12)
num2[x] = "C";
else if (num % base == 13)
num2[x] = "D";
else if (num % base == 14)
num2[x] = "E";
else if (num % base == 15)
num2[x] = "F";
else
*num2[x] = num % base;

num = num % base;
x++;
printf("%d, %s", num, num2[x]); fflush(stdout);
}

while (x >= 0){
printf("%s", num2[1]);
fflush(stdout);
x--;
}

printf("\n");
fflush(stdout);

return 0;
}


Through checking the errors with gdb and print statements, I've come to the conclusion that the error stems from something in line 14:

while ((num % base) > 1) {


I'm relatively new to C, most of what I've done has been in Java.

Answer

Both of the earlier answers are right (i.e. @Sourav and @Tony). The exact reason among these 2 depends on the input provided during an execution instance.

  1. Say, your input is num=3, base=16.
    Then, your program will crash at the line -
    *num2[x] = num % base;

    num2[x] points to NULL since 'num2' is a global array.

  2. Say, your input is num=13, base=16.
    Then, your program will crash at the line -
    num2[x] = "D";

    This is because 'num' remains a constant at 13 (num = num % base) and as a result 'x' would eventually be a value way beyond 49 and num2[x] will be accessing an illegal location.


Also, your program is logically flawed; you will not get the output that you desire with your current approach. Your program needs to be tweaked slightly -

char num2[50]; /* Array of chars, instead of array of pointers to char. */

. . .

/* Add check to verify that base is a value between 2 and 16. */

while ((num % base) > 0){  /* Greater than 0, not 1. */
    if(num % base == 10)
        num2[x] = 'A'; /* Use a character instead of a string. */
    else if (num % base == 11)
        num2[x] = 'B';
    else if (num % base == 12)
        num2[x] = 'C';
    else if (num % base == 13)
        num2[x] = 'D';
    else if (num % base == 14)
        num2[x] = 'E';
    else if (num % base == 15)
        num2[x] = 'F';
    else
        num2[x] = (num % base) + '0'; /* Convert the number to its character form. */

    num /= base;  /* Duh! */
    printf("%d, %c", num, num2[x]); fflush(stdout); /* %c instead of %s*/
    x++;
}

while (x >= 0){
    printf("%c", num2[x]); fflush(stdout);  /* %c instead of %s*/
    x--;
}