Thread: Segmentation fault

  1. #1
    Registered User
    Join Date
    Feb 2010
    Posts
    14

    Thumbs down Segmentation fault

    Hello All,

    I'm new to C programming and have been set an assignment. We are to read in float values from a text file and insert them into two arrays, then perform certain manipulations to the stored values. I have managed to insert the data into separate arrays (one for each column), but when trying to sum together all the values, I end up with a segmentation fault - despite trying different variable types.

    Can somebody please help me with this code? Below is the code so far and I've attached the text file.

    Regards,

    Paul.

    Code:
    /* 
     * File:   newmain.c
     * Author: paul
     *
     * Created on 09 February 2010, 19:37
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    /*
     * 
     */
    int main() {
        FILE *file;
        float col1[100000];
        float col2[100000];
        /* make sure it is large enough to hold all the data! */
        int i, j;
        long k;
        float sum;
        float average;
    
        file = fopen("/home/paul/assessment2_data.txt", "r");
    
        if (file == NULL) {
            printf("Error: can't open file.\n");
            return 1;
        } else {
            printf("File opened successfully.\n");
    
            i = 0;
    
            while (!feof(file)) {
                /* loop through and store the numbers into the array */
                fscanf(file, "%f\t%f", &col1[i], &col2[i]);
                i++;
            }
        }
    
        printf("Amount of numbers read: %d\n\n", i);
        printf("The numbers are:\n");
    
        printf("\nColumn 1:\n\n");
        for (j = 0; j < i; j++) { /* now print them out 1 by 1 */
            printf("%f\n", col1[j]);
        }
        printf("\nColumn 2:\n\n");
        for (j = 0; j < i; j++) {
            printf("%f\n", col2[j]);
        }
    
        sum = 0;
        average = 0;
    
        for (k = 0; k <= sizeof(col1); k++){
            printf("Loop number: %d\n", k);
            sum += col1[k];
        }
        printf("The sum of Column 1 is: %f", sum);
    
        fclose(file);
        return 0;
    }

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    sizeof returns the number of bytes something takes up. For a float, that's num_elements * sizeof(float), way out the number of elements.
    Furthermore, an array index is only inside the bounds 0< n < elements - 1 (not elements, as you seem to think). Hence, if an array has 10 elements, valid indexes are in the range of 0 to 9. And sizeof will (probably) return 40 for a float array of 10 elements.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Feb 2010
    Posts
    14
    Thanks for your help Elysia - I realised it would be much easier to re-use the counter 'i' as this will have effectively 'counted' the number of elements into the array. I *think* this is problem solved... for now! Cheers, Paul.

  4. #4
    Registered User
    Join Date
    Feb 2010
    Posts
    14
    OK - I've managed to resolve this issue, only to find another later down the line! When working out the minimum value stored within the two arrays I get an unexpected output for the first column of '0.000000' yet the code works for the second column. Here is my current code:

    Code:
    /*
     * File:   newmain.c
     * Author: Paul R. Smith
     *
     * Created on 09 February 2010, 19:37
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    /*
     *
     */
    int main() {
        FILE *file;
        float col1[100000];
        float col2[100000];
        /* make sure it is large enough to hold all the data! */
        int arr_ele, j, k, l, m, n, o, gotNum;
        float sum_col1, sum_col2;
        float average_col1, average_col2;
        float max_col1, max_col2, min_col1, min_col2;
    
        if ((file = fopen("/home/paul/assessment2_data.txt", "rt")) == NULL) {
            printf("\nError opening file\n");
            return 1;
        }
        arr_ele = 0;
        do {
            gotNum = 0;
            gotNum = fscanf(file, "%f%f", &col1[arr_ele], &col2[arr_ele]);
            if (gotNum > 1)
                printf("\n%f   %f", col1[arr_ele], col2[arr_ele]);
            arr_ele++;
    
        } while (gotNum > 1);
    
        printf("\nAmount of numbers read: %d\n\n", arr_ele);
        printf("The numbers are:\n");
    
        sum_col1 = 0;
        sum_col2 = 0;
    
        for (k = 0; k < arr_ele; k++) {
            sum_col1 += col1[k];
        }
    
        for (k = 0; k < arr_ele; k++) {
            sum_col2 += col2[k];
        }
    
        printf("The sum of Column 1 is: %f\n", sum_col1);
        printf("The sum of Column 2 is: %f\n", sum_col2);
    
        average_col1 = 0;
        average_col2 = 0;
    
        average_col1 = sum_col1 / arr_ele;
        average_col2 = sum_col2 / arr_ele;
    
        printf("The average of Column 1 is: %f\n", average_col1);
        printf("The average of Column 2 is: %f\n", average_col2);
    
        for (m = 0; m < arr_ele; m++) {
            if (col1[m] > max_col1) {
                max_col1 = col1[m];
            } else if (col1[m] < min_col1) {
                min_col1 = col1[m];
            }
        }
    
        for (m = 0; m < arr_ele; m++) {
            if (col2[m] > max_col2) {
                max_col2 = col2[m];
            } else if (col2[m] < min_col2) {
                min_col2 = col2[m];
            }
        }
    
        printf("The maximum value in Column 1 is: %f\n", max_col1);
        printf("The maximum value in Column 2 is: %f\n", max_col2);
    
        printf("The minimum value in Column 1 is: %f\n", min_col1);
        printf("The minimum value in Column 2 is: %f\n", min_col2);
    
        fclose(file);
        return 0;
    }
    The input text file remains the same as per my earlier post. I simply can't fathom out for why, any help greatly appreciated!

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The max and min_col* variables aren't initialized.
    You should learn to use a debugger to find issues such as these. It's trivial.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > while (gotNum > 1);
    You should add
    while (gotNum > 1 && arr_ele < 100000 );

    Also, your arrays are filled with junk data to begin with, AND you still do arr_ele++; even if the read fails.
    Code:
    if ( fscanf(file, "%f%f", &col1[arr_ele], &col2[arr_ele]) == 2 ) {
      arr_ele++;
    } else {
      // error
    }
    is much safer.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Feb 2010
    Posts
    14
    With all due respect, this may be "trivial" to you though I've only been programming for a few days! I do have a debugger and it runs without fail. You say they aren't initialised but I've now done this (correctly I hope!) and they're set to 0... still getting strange outputs. Thanks!

  8. #8
    Registered User
    Join Date
    Feb 2010
    Posts
    14
    Thanks Salem,

    I tried your suggested code but this resulted in my program only reading in 1 value from the text file?! I'm really quite confused now haha!

    I slotted the if/else statement into the place of the do/while loop... I think I've done this wrong. Could you please show me how you intended then hopefully I'll get my head round this. I've spent far too long looking at the same code... my brain is frazzled!

    Cheers,

    Paul.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by sirsmilealot View Post
    With all due respect, this may be "trivial" to you though I've only been programming for a few days! I do have a debugger and it runs without fail. You say they aren't initialised but I've now done this (correctly I hope!) and they're set to 0... still getting strange outputs. Thanks!
    I say trivial because it's easy to learn and spot. Doesn't require any fancy knowledge at all.
    Some compilers will even warn about these things.

    If you set a breakpoint where it fails and check the contents of your variables, you WILL find something amiss. Trivial, yes?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Post 10 lines of your text file please.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #11
    Registered User
    Join Date
    Feb 2010
    Posts
    14
    Thanks Elysia - I'll have a go at this now.

    Salem - The full text file is attached above in an earlier post though here are 10 lines in any case:

    Code:
    2.67	2.464
    2.393	1.228
    2.167	0.657
    5.047	2.033
    7.993	2.169
    7.917	1.249
    4.874	1.66
    4.384	2.166
    5.355	2.896
    4.505	2.637
    There are no line spaces between rows. Cheers!

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Yet another example of why I don't like using anything other than fgets() for reading files....
    Code:
    $ cat foo.c
    /*
    * File:   newmain.c
    * Author: Paul R. Smith
    *
    * Created on 09 February 2010, 19:37
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    
    /*
    *
    */
    int main() {
      FILE *file;
      float col1[100000] = { 0 };
      float col2[100000] = { 0 };
      /* make sure it is large enough to hold all the data! */
      int arr_ele;
      
      if ((file = fopen("assessment2_data.txt", "rt")) == NULL) {
        printf("\nError opening file\n");
        return 1;
      }
      arr_ele = 0;
      do {
        if ( fscanf(file, "%f%f", &col1[arr_ele], &col2[arr_ele]) == 2 ) {
          printf("\n%f   %f", col1[arr_ele], col2[arr_ele]);
          arr_ele++;
        } else {
          printf("Ooops\n");
          break;  // if you don't have this, it loops FOREVER
        }
      } while (arr_ele < 100000 );  // delete the got_num count, it's unused.
      printf("\nAmount of numbers read: %d\n\n", arr_ele);
      
      rewind(file);
      clearerr(file);
      arr_ele = 0;
      {
        char buff[100];
        while ( fgets( buff, sizeof buff, file ) != NULL && arr_ele < 100000 ) {
          if ( sscanf(buff, "%f%f", &col1[arr_ele], &col2[arr_ele]) == 2 ) {
            printf("\n%f   %f", col1[arr_ele], col2[arr_ele]);
            arr_ele++;
          } else {
            printf("Ooops\n");
          }
        }
      }
      printf("\nAmount of numbers read: %d\n\n", arr_ele);
      
      fclose( file );
      return 0;
    }
    $ gcc -W -Wall -ansi -pedantic -O2 foo.c
    $ ./a.out 
    
    2.670000   2.464000
    2.393000   1.228000
    2.167000   0.657000
    5.047000   2.033000
    7.993000   2.169000
    7.917000   1.249000
    4.874000   1.660000
    4.384000   2.166000
    5.355000   2.896000
    4.505000   2.637000Ooops
    
    Amount of numbers read: 10
    
    
    2.670000   2.464000
    2.393000   1.228000
    2.167000   0.657000
    5.047000   2.033000
    7.993000   2.169000
    7.917000   1.249000
    4.874000   1.660000
    4.384000   2.166000
    5.355000   2.896000
    4.505000   2.637000
    Amount of numbers read: 10
    The fgets() approach is very much preserved.
    With fscanf(), you're hoping the structure of the file is good. Any minor problem with it, and fscanf is likely to get stuck in a loop (just remove the break statement!)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    Feb 2010
    Posts
    14
    Thank you ever so much Salem, I understand now, much better the fgets() approach! Thanks also to Elysia for your comments!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault
    By bennyandthejets in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2005, 05:04 PM
  2. Segmentation fault
    By NoUse in forum C Programming
    Replies: 4
    Last Post: 03-26-2005, 03:29 PM
  3. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 01:33 PM
  4. Annoying Segmentation Fault
    By Zildjian in forum C++ Programming
    Replies: 7
    Last Post: 10-08-2004, 02:07 PM
  5. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM