首页 > 解决方案 > 使用数组时无法找出“线程 1:EXC_BAD_ACCESS”错误

问题描述

我正在研究一种按升序对输入整数进行排序的算法。

输入应该是排序的

5
32
45
32
55
67

和排序的输出

32
32
45
55
67

其中第一个整数输入是将输入的整数个数。

nb 输入的整数 n 为 1 <= n <= 10,000,000。

这是我的代码:

#include <stdio.h>

int main() {
    int N;
    scanf("%d", &N); // receives the number of integers that will be inputted
    int countArray[10000000] = {0}; // creates an array that will store the number of times a number is inputted. the inputted number is the corresponding address e.g. countArray[number-1] stores the amount of times the number 'number' is inputted.

    int inputArray[N]; // creates an array of the numbers inputted
    for (int i=0; i<N; i++) {
        scanf("%d", &inputArray[i]); // receives the numbers inputted and stores them in the inputArray
    }
    for (int i=0;i<N;i++) {
        countArray[inputArray[i]-1]++; // counts the number of times a number occurs in inputArray and increments the corresponding value in the countArray.
    }
    int i=0;
    while (i<10000000) {
        if (countArray[i] > 0) {
            for (int j=0;j<countArray[i];j++) { // prints out the numbers only if count is greater than 0.
                printf("%d\n", i+1);
            }
        }
        i++;
    }
    return 0;
}

我知道我的代码不是对输入进行排序的最有效方法;我只是好奇为什么当数组的大小为 10,000,000 而不是 1,000,000 时出现“线程 1:EXC_BAD_ACCESS”错误。如果数组的大小为 1,000,000,它工作得很好,但当它是 10,000,000 时就不行。

标签: arrayscsortingmemoryexc-bad-access

解决方案


您的示例代码至少可以编译,但不能运行。它在启动时出现段错误。

使用 GCC + Linux,我得到Segmentation fault (core dumped)它并以 code 退出139,而在我的带有 Clang 的 Mac 上,我得到Segmentation fault: 11相同的退出代码。我怀疑您EXEC_BAD_ACCESS的版本具有相同的基本问题。

正如@tevemadar所指出的,您在堆栈中要求大约 40MiB个数据,很明显,您不会得到这些数据。

所以,而不是这个:

int countArray[10000000];

这样做

int *countArray = malloc(10000000*sizeof(int));

或者

static int countArray[10000000];

哪个应该起作用(不要忘记检查NULL),因为malloc()将返回一个指向它在堆中分配的内存的指针,并且全局变量也放在堆中,其中大小限制不像堆栈那样严格,并且对于大多数实际目的而言,记住这一点并不重要。


现在,到我的一些漫谈-

您实际上远远超出了允许的堆栈大小。我不自称是专家,但到目前为止,这对你来说肯定也是不言而喻的。

您的尝试有点滥用堆栈,可能是由于没有被告知堆栈目的背后的想法 - 大多数 C 教科书和课程都犯了这样的错误:(

我不是专家,不会为你毁了概念的美感,但总结一下——

堆栈用于存储较小的函数局部变量,例如计数器、要打印的字符串、返回值等。一般来说,除非你或它,否则它就是所有东西都会去的malloc()地方。它适用于小而方便的变量,这对.fopen()staticmalloc()

是一个巨大的内存区域,用于批量使用,如链表、长数组、树、大结构等等。它是您应该存储存储大量数据的大型变量的地方。


因此,TL;DR,将堆用于大型数据类型,使用堆栈的小变量,这对malloc().


推荐阅读