Getting a bad access code in xcode

Discussion in 'Mac Programming' started by 31rhcp, Aug 17, 2013.

  1. macrumors member

    Joined:
    May 18, 2010
    #1
    I am trying to compile a file for a MOOC that I am taking. Without going into details, the program has to read 1000000 long ints into an array. The program works very well with smaller array lengths, but it gives me an issue here. I get a Thread 1: EXC_BAD_ACCESS (code=2,address=0x7fff5eca9ba8) error in Xcode.

    Any ideas on how to fix this?

    Code:
    #define LEN 999999
    int x = 0;
    Code:
    file = fopen("address to the location on my comp", "r");
        if (file == NULL)
        {
            printf("File not found!\n");
        }
        long int arr[LEN];
        long int sorted[LEN];
        long int temp;
        int found[20001] = { 0 };
        for (int x = 0; (x < LEN + 1) && !feof(file); x++)
        {
            fscanf(file, "%ld", &temp);
            arr[x] = temp;
        }
        fclose(file);
     
  2. subsonix, Aug 17, 2013
    Last edited: Aug 17, 2013

    macrumors 68040

    Joined:
    Feb 2, 2008
    #2
    This looks like a fence post error, that is, your array is declared as being size LEN but since and array is indexed from 0, LEN + 1 is one over.

    Edit: also watch out for using feof in the loop like that, it's only set once eof is read, which is one read too many. You can actually use fscanf directly in the loop condition since it returns the amount of items read, in your case that's 1, or 0 if there is no more to read.
     
  3. thread starter macrumors member

    Joined:
    May 18, 2010
    #3
    You are correct there is a fence post error there. However, I found that the solution is how I allocated the array. Dynamic allocation solved my problem.

    long* arr = new long[LEN];
     
  4. macrumors 68040

    Joined:
    Feb 2, 2008
    #4
    Ok I see, so you used it in a different scope not shown in the snippet above?
     
  5. thread starter macrumors member

    Joined:
    May 18, 2010
    #5
    The program was an assignment for a MOOC I was taking. I had to find out how many integers in the range [-10000 to 10000] had at least one pair of numbers in a given 1000000 integer array that summed to them.

    So basically, all 1000000 integers are read into the array arr[] and then sorted into sorted[] for searching purposes later on. sorted[] gets passed around a lot, but arr[] is only used here.

    Hopefully that answers your question. I'm just a novice. Xcode was giving me the error at the line

    Code:
    file = fopen("address to the location on my comp", "r");
    so I assumed the file IO/array storage was the issue.
     
  6. macrumors 6502

    Joined:
    Apr 24, 2008
    #6
    Is this a MOOC about C++? In my humble opinion, the first class should explain never to use "new".
     
  7. macrumors 6502

    ElectricSheep

    Joined:
    Feb 18, 2004
    Location:
    Wilmington, DE
    #7
    Off-by-one errors aside, the reason why your program worked well with smaller array lengths but failed with larger lengths is due to limitations on how large the stack can grow. On Mac OS X, the default stack limit is around 8 megs, with a hard upper limit of 65 megs. Just a single stack-allocated array of a million long ints is going to consume most of your stack space, and you are going to find yourself running into problems very quickly.

    This is a case where use of new to allocate on the heap is advisable. However, you really shouldn't use raw pointers as the onus is upon you track ownership and delete them when finished. Instead, leverage something like a unique_ptr:

    Code:
    #include <memory>
    ...
    
    std::unique_ptr<long int[]> arr(new long int[LEN]);
    std::unique_ptr<long int[]> sorted(new long int[LEN]);
    
    ...
    
    The array is allocated on the heap, but you get the benefit of the management of automatic variables; once arr goes out of scope, the array will be deleted.
     
  8. macrumors newbie

    Joined:
    Nov 25, 2011
    #8
    Index out of bounds

    I think the LEN declaration is also not sufficient for storing 1000000 elements. LEN should declared to 1000000 not 999999. By declaring LEN as:
    #define LEN 999999

    And then doing:
    long int arr[LEN];

    Means you will have array variable which can hold 999999 long int values, ranged from index 0 to 999998.

    or even:
    long * arr = new long[LEN];
    will also declare a pointer which points to some memory area which can hold up to 999999 long int values, not 1000000 long int values.

    So should change LEN declaration to #define LEN 1000000;
     

Share This Page