«EXC_BAD_ACCESS: невозможно восстановить ранее выбранный кадр» Ошибка, размер массива? - PullRequest
5 голосов
/ 16 июня 2010

У меня есть алгоритм для создания сита Эратосфена и извлечения из него простых чисел. Он позволяет вам ввести максимальное значение для сита, а алгоритм дает вам простые числа ниже этого значения и сохраняет их в массиве в стиле 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.)

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

EDIT: Вот как выглядит код (он не завершен, поскольку он завершается с ошибкой в ​​последней опубликованной строке). Я использую сборщик мусора.

/*--------------------------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;

}

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

Ответы [ 4 ]

7 голосов
/ 16 июня 2010

Вы не переполняете переменные; Вы переполняете стек. Когда вы создаете массив типа 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() память, когда вы закончите с ней, или у вас будет утечка.

2 голосов
/ 16 июня 2010

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

/* 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) == 8, вы поместите в стек два массива по 500000 элементов, но не два массива по 550000 элементов.

0 голосов
/ 16 февраля 2012

У меня тоже была эта проблема.Оказывается, у меня была петля.Я вызывал метод изнутри сам по себе.

0 голосов
/ 16 июня 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...