使用数组时无法找出“线程1:EXC_BAD_ACCESS”错误

问题描述

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

输入内容应为

5
32
45
32
55
67

和排序输出

32
32
45
55
67

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

n.b。输入的整数n为1

这是我的代码

#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时会出现“线程1:EXC_BAD_ACCESS”错误。如果数组的大小为1,000,则效果很好,但当数组的大小为10,000时,效果就很好。

解决方法

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

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

@tevemadar指出,您要在堆栈中请求约40 MiB个数据,很明显,您不是会得到。

所以,代替这个:

int countArray[10000000];

执行此操作

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

OR

static int countArray[10000000];

应该有效(不要忘记检查NULL),因为malloc()将返回 pointer 到它在 heap 中分配的内存中,并且全局变量也放入堆中,在堆中,大小限制没有 stack 那样严格,对于大多数情况实际目的并不重要,要牢记在心。


现在,到我的一些杂物-

实际上,您将非常多超出允许的堆栈大小。我并没有声称自己是专家,但是到目前为止,对于您来说,这当然也是不言而喻的。

您的尝试有点像是栈的滥用,也许是由于没有被告知栈目的背后的想法-大多数C教科书和课程都对:(

我不是专家,不会为您破坏这个概念的美,而是总结一下-

堆栈 用于存储函数的更小的局部变量,例如计数器,要打印的字符串,返回值等。一般来说,一切都会进行,除非您malloc()fopen()static。对于小的方便变量(对malloc()来说很愚蠢)也可以。

是一个巨大的内存区域,旨在供大量使用,如链接列表中一样,长数组,树木,大型结构等。在此处应 存储大小很大的变量,这些变量将存储大量的数据


因此,TL; DR,将堆用于大型数据类型,使用小变量堆栈,这对malloc()来说很愚蠢。