“EXC_BAD_ACCESS: Не мог восстановить ранее выбранный кадр” Ошибка, размер Массива?

У меня есть алгоритм для создания решета Эратосфена и получения по запросу начал от него. Это позволяет Вам ввести макс. значение для решета, и алгоритм дает Вам начала ниже того значения и хранит их в массиве c-стиля.

Проблема: Все хорошо работает со значениями до 500 000, однако когда я ввожу большое значение - при выполнении - оно дает мне следующее сообщение об ошибке в XCode:

Program received signal:  “EXC_BAD_ACCESS”.
warning: Unable to restore previously selected frame.
Data Formatters temporarily unavailable, will re-try after a 'continue'. (Not safe to call dlopen at this time.)

Моя первая идея состояла в том, что я не использовал достаточно большие переменные, но как я использую 'неподписанное долгое длинное целое', это не должно быть проблемой. Также отладчик указывает на меня на точку в моем коде, где точке в массиве присваивают значение. Поэтому интересно, там максимальный предел массиву? Если да: я должен использовать NSArray вместо этого? Если не, то, что вызывает эту ошибку на основе этой информации?

Править: Это - то, на что код похож (это не завершено, поскольку это перестало работать в последней отправленной строке). Я использую сборку "мусора".

/*--------------------------SET UP--------------------------*/
    unsigned long long int upperLimit = 550000;             // 
    unsigned long long int sieve[upperLimit];
    unsigned long long int primes[upperLimit];
    unsigned long long int indexCEX;
    unsigned long long int primesCounter = 0;

// Fill sieve with 2 to upperLimit
for(unsigned long long int indexA = 0; indexA < upperLimit-1; ++indexA) {
        sieve[indexA] = indexA+2;
}


unsigned long long int prime = 2;

/*-------------------------CHECK & FIND----------------------------*/
while(!((prime*prime) > upperLimit)) {

    //check off all multiples of prime
    for(unsigned long long int indexB = prime-2; indexB < upperLimit-1; ++indexB) {

        // Multiple of prime = 0
        if(sieve[indexB] != 0) {
            if(sieve[indexB] % prime == 0) {
                sieve[indexB] = 0;
            }
        }
    }

    /*---------------- Search for next prime ---------------*/
    // index of current prime + 1
    unsigned long long int indexC = prime - 1;

    while(sieve[indexC] == 0) {
        ++indexC;
    }
    prime = sieve[indexC];

    // Store prime in primes[]
    primes[primesCounter] = prime; // This is where the code fails if upperLimit > 500000
    ++primesCounter;

    indexCEX = indexC + 1;

}

Как Вы можете или не можете видеть, то, что я - очень новичок. Любые другие предложения приветствуются, конечно, :)

5
задан Job 16 June 2010 в 13:50
поделиться

3 ответа

Вы не переполняете переменные; вы переполняете стек. Когда вы создаете массив вроде int myArray [500] , вы объявляете в стеке 500 int s. Нормальный размер стека - 8 МБ. Только ваши два массива имеют размер около 8,4 МБ (8 байт * 550000 / (1024 ^ 2) = 4,2 МБ). Вместо этого вы должны использовать память кучи (из malloc () ). Это будет примерно так:

int upperLimit = 550000;
unsigned long long *sieve = malloc(sizeof(long long) * upperLimit);
unsigned long long *primes = malloc(sizeof(long long) * upperLimit);
unsigned long long indexCEX;
unsigned long long primesCounter = 0;

Не забывайте, что вам нужно будет free () памяти, когда вы закончите с ней, или вы закончите утечку.

7
ответ дан 14 December 2019 в 01:01
поделиться

Насколько я знаю, "EXC_BAD_ACCESS" получается, когда вы пытаетесь работать с уже освобожденной памятью. Для отладки вы можете использовать класс NSZombie. Это может помочь: http://www.cocoadev.com/index.pl?DebuggingAutorelease

0
ответ дан 14 December 2019 в 01:01
поделиться

Вы используете массивы, выделенные на стеке. Вы можете выделить больше памяти, если используете динамическое распределение памяти:

/* program setup */
unsigned long long *sieve = malloc(sizeof(*sieve) * upperLimit);
unsigned long long *primes = /* -- "" -- */
/* etc, free() at program end */

Ограничение стека в вашей системе OS X, вероятно, составляет 8 Мб. Если sizeof(unsigned long long long) == 8 в вашей системе, то в стек поместится два массива по 500000 элементов, но не два массива по 550000 элементов.

2
ответ дан 14 December 2019 в 01:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: