“EXC_BAD_ACCESS:无法恢复以前选择的帧”错误,数组大小?

时间:2010-06-16 08:44:59

标签: c objective-c arrays xcode exception

我有一个算法来创建Eratosthenes的筛子并从中拉出素数。它允许您输入筛子的最大值,算法会为您提供低于该值的质数,并将它们存储在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吗?如果不是,那么基于此信息导致此错误的原因是什么?

编辑: 这就是代码的样子(它不完整,因为它在发布的最后一行失败了)。我正在使用垃圾收集。

/*--------------------------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 个答案:

答案 0 :(得分:7)

你没有溢出变量;你堆满了。当您创建像int myArray[500]这样的数组时,您在堆栈上声明了500 int个。正常堆栈大小为8 MB。你的两个阵列大约是8.4 MB(8字节* 550000 /(1024 ^ 2)= 4.2 MB)。你应该在这里使用堆内存(来自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()记忆,否则你最终会泄漏。

答案 1 :(得分:2)

您正在使用堆栈上分配的数组。如果使用动态内存分配,则可以分配更多内存:

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

OS X系统的堆栈限制可能为8 MiB。如果您的系统上有sizeof(unsigned long long) == 8,那么您的堆栈中将包含两个500000元素数组,而不是两个550000元素数组。

答案 2 :(得分:0)

据我所知,当您尝试使用已释放的内存时,会收到“EXC_BAD_ACCESS”。要调试它,您可以使用NSZombie类。这可能有所帮助:http://www.cocoadev.com/index.pl?DebuggingAutorelease

答案 3 :(得分:0)

我也有这个问题。原来我有循环。我不小心从内部调用了一种方法。