0

I am writing code to sort a txt file of int's and then display them when the user asks for a number at a certain index but every time I run my code I get a segmentation fault. What can I do to fix this?

void insert_sorted(long *sorted, int count, long value)
{
    int i = 0;

    sorted[1024] = value;
    if (count == 0) return;
    for (i = count; i >= 0; i--) {
        if (value < sorted[i - 1])
            sorted[i] = sorted[i - 1];
        else break;
    }
    sorted[i] = value;
}
int main(int argc, char *argv[])
{
    FILE *infile = NULL;
    int count = 0;
    long sorted[1024];
    long value;
    int i = 0;
    if (argc < 2) {
        fprintf(stderr, "Usage : %s <file_name>/n", argv[0]);
        return 1;
    }
    infile = fopen(argv[1], "r");
    if (NULL == infile) {
        perror("fopen");
        return -1;
    }
    /* while file not ends */
    while (!feof(infile)) {
        fscanf(infile, "%ld\n", &value); /* fetch value */
        insert_sorted(sorted, count, value); /* sort */
        ++count; /* increase number of sorted values */
    }
    /* display values */
    printf("Enter Index : ");
    int index;
    scanf("%d", &index);
    if (index == -1)
        fclose(infile);
    printf("%d ", sorted[index]);

    /* cleanup */
    if (infile) {
        fclose(infile);
        infile = NULL;
    }
    return 0;
}
Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
Patrick
  • 13
  • 1
  • 2
    Just a tip: Your should indent your code better. Otherwise it's very hard to read the code (for you and for other persons). – Benjamin J. Sep 07 '18 at 20:58
  • it's also difficult to edit a post that's mostly code. I wasn't able to save my edit thanks to a warning. – Tim Randall Sep 07 '18 at 21:00
  • 1
    What's the index of the last element of an array of size 1024? – Dave Newton Sep 07 '18 at 21:01
  • One issue could be `sorted[1024] = value;` in `insert_sorted()`. If you want to insert the value at the last array position it would be 1023 and not 1024. – Benjamin J. Sep 07 '18 at 21:03
  • 4
    This site is a _terrible_ debugger! What have you tried so far? Have you traced the fault to a specific line? https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ –  Sep 07 '18 at 21:08
  • 1
    Welcome to SO! This site isn't a free debugging service, so you should show your attempts at debugging the code with a debugger or other simpler methods such as debug print statements. You can also test each part of the code separately to figure out exactly which part of the code is causing the problem, and make a [mcve]. This won't be the only time you end up with a bug in your code, and learning to debug your programs will help you much more than having someone find the bug for you. Debugging your own code is an important skill in programming. See http://idownvotedbecau.se/nodebugging/. – eesiraed Sep 08 '18 at 04:41

4 Answers4

2

The operation in sorted[1024] =value; will crash your program. The size of sorted array is only 1024 so that the bigest index is 1023.

One way to fix that is to change the size of sorted to 1025 in the main() function.

An other operation in the for loop that can crash the program : while i =0, access to sorted [ i - 1 ] will catch an exception.

tunglt
  • 1,022
  • 1
  • 9
  • 16
  • 2
    @GovindParmar I don't think that is correct; you are allowed to have a one-past-the-end pointer, but as soon as you dereference it you enter the land of undefined behavior. https://stackoverflow.com/a/1021032/3282436 – 0x5453 Sep 07 '18 at 21:16
  • @0x5453 Thanks for the clarification! – Govind Parmar Sep 07 '18 at 21:16
2

The size of array sorted is 1024:

    long sorted[1024];

which means the valid index of array sorted range from 0 to 1023.

In insert_sorted() function, you are trying to access sorted array beyond its range:

    sorted[1024] = value;
           ^^^^

Accessing an element of array beyond its size is undefined behavior which includes program may give segmentation fault.

In fact, there is a logical error in insert_sorted() function. It is never storing the first value at appropriate location in the sorted array because of this count value check:

    if (count == 0) return;

For the first time count value will be 0 and the function return without storing value at appropriate location in sorted array. Also, you should put a check on count value and if it is greater than the array size, function should give appropriate error message. You can do:

#define ARR_SZ 1024

void insert_sorted(long *sorted, int count, long value) {
    int i = 0;

    if (count > ARR_SZ) {
        fprintf (stderr, "Array is exhausted");
        //may you want to change the return type of function from void to 
        //int and return a value in case of error.
        //Based on the return value, the caller of this function can take
        //appropriate action.
        return;
    }

    for (i = count; i > 0; i--) {
        if (value < sorted[i - 1])
            sorted[i] = sorted[i - 1];
        else 
            break;
    }
    sorted[i] = value;
}

int main(int argc, char *argv[])
{
    FILE *infile = NULL;
    int count = 0;
    long sorted[ARR_SZ];
    ......
    ......
    ......
}

When you are taking index input from user, make sure to add a check whether it is less than 0 or greater than or equal to count. If it is, you should not access sorted[index].

    scanf("%d", &index);

    if ((index >= count) || (index < 0)) {
         //print error message and do not access sorted[index]
    }

You don't need this:

    if (index == -1)
        fclose(infile);

because of this when user enters -1, the fclose is getting called twice for infile. Make sure once you have closed the FILE * of a opened file, don't call fclose again on it.

H.S.
  • 11,654
  • 2
  • 15
  • 32
1

Segmentation fault appear when you try to write in an element array with a key that is bigger than his dimension. In this case you are writing on

sorted[1024] = value

that has as biggest key 1023 (long sorted[1024] means from 0 to 1023).

You should change

long sorted[1024];

with

long sorted[1025];

else you should change

sorted[1024] = value;

with

sorted[1023] = value;

I didn't read your code for telling you which is better.

Heichou
  • 311
  • 4
  • 13
0

What can I do to fix this?

You can run the program in a debugger.

You can either step through the code, one instruction at a time, inspecting the values of your variables as you go, or you can simply let the program run under the watchful eye of the debugger. If and when the program causes a seg-fault, the debugger will interrupt it at the exact point of failure, allowing you to see which code is responsible. It will even let you see the values of the variables involved, if there's any doubt about why the code did what it did.

Tim Randall
  • 4,040
  • 1
  • 17
  • 39