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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3051790/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 19:27:50  来源:igfitidea点击:

"EXC_BAD_ACCESS: Unable to restore previously selected frame" Error, Array size?

cobjective-carraysxcodeexception

提问by Job

I have an algorithm for creating the sieve of Eratosthenes and pulling primes from it. It lets you enter a max value for the sieve and the algorithm gives you the primes below that value and stores these in a c-style array.

我有一个算法来创建 Eratosthenes 的筛子并从中提取素数。它允许您输入筛网的最大值,算法会为您提供低于该值的素数并将它们存储在 c 样式数组中。

Problem: Everything works fine with values up to 500.000, however when I enter a large value -while running- it gives me the following error message in xcode:

问题:对于高达 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.)

My first idea was that I didn't use large enough variables, but as I am using 'unsigned long long int', this should not be the problem. Also the debugger points me to a point in my code where a point in the array get assigned a value. Therefore I wonder is there a maximum limit to an array? If yes: should I use NSArray instead? If no, then what is causing this error based on this information?

我的第一个想法是我没有使用足够大的变量,但是当我使用“unsigned long long int”时,这应该不是问题。此外,调试器将我指向代码中的一个点,其中数组中的一个点被分配了一个值。因此我想知道数组是否有最大限制?如果是:我应该改用 NSArray 吗?如果否,那么根据此信息导致此错误的原因是什么?

EDIT: This is what the code looks like (it's not complete, for it fails at the last line posted). I'm using garbage collection.

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

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

}

As you may or may not see, is that I am -very much- a beginner. Any other suggestions are welcome of course :)

正如您可能会或可能不会看到的那样,我 - 非常 - 一个初学者。当然,欢迎任何其他建议:)

回答by Chuck

You're not overflowing the variables; you're overflowing the stack. When you create an array like int myArray[500], you're declaring 500 ints on the stack. The normal stack size is 8 MB. Your two arrays alone are about 8.4 MB (8 bytes * 550000 / (1024^2) = 4.2 MB). You should be using heap memory (from malloc()) here instead. So it would be like this:

你没有溢出变量;你正在溢出堆栈。当您创建一个类似 的数组时int myArray[500],您将int在堆栈上声明 500秒。正常的堆栈大小为 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;

Don't forget that you'll need to free()the memory when you're done with it or you'll end up leaking.

不要忘记,完成后您将需要free()内存,否则最终会泄漏。

回答by u0b34a0f6ae

You are using arrays allocated on the stack. You can probably alloc more memory if you use dynamic memory allocation:

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

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

The stack limit on your OS X system is probably 8 MiB. If sizeof(unsigned long long) == 8on your system, you'll fit two 500000-element arrays in your stack, but not two 550000-element arrays.

您的 OS X 系统上的堆栈限制可能是 8 MiB。如果sizeof(unsigned long long) == 8在您的系统上,您将在堆栈中放入两个 500000 元素的数组,但不会放入两个 550000 元素的数组。

回答by kpower

As I know, "EXC_BAD_ACCESS" is received, when you try to work with already freed memory. To debug this you can use NSZombie class. This may help: http://www.cocoadev.com/index.pl?DebuggingAutorelease

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

回答by Will Larche

I also had this problem. Turns out I had loop. I was calling a method from within itself by accident.

我也有这个问题。原来我有循环。我无意中从内部调用了一个方法。