C 尝试声明int数组时数组声明失败

C 尝试声明int数组时数组声明失败,c,C,我学习和编码排序算法已经有一段时间了,最近我用C编写了合并排序,我还编写了一个排序测试函数来测试我编写的函数。在sort test函数中,我声明了一个数组并给它分配了随机值,但是当数组大小达到1000000时,程序崩溃了。为什么会这样 sort\u test.c merge\u sort.h merge\u sort.c #包括 #包括“sort_test.h” #包括“merge_sort.h” int main(){ intSortTest(); 返回0; } 无效合并排序(int*arr、

我学习和编码排序算法已经有一段时间了,最近我用C编写了合并排序,我还编写了一个排序测试函数来测试我编写的函数。在sort test函数中,我声明了一个数组并给它分配了随机值,但是当数组大小达到1000000时,程序崩溃了。为什么会这样

sort\u test.c
merge\u sort.h
merge\u sort.c
#包括
#包括“sort_test.h”
#包括“merge_sort.h”
int main(){
intSortTest();
返回0;
}
无效合并排序(int*arr、int开始、int结束){
如果(开始<结束){
整数中值=(结束+开始)/2;
合并排序(arr、开始、中间值);
合并排序(arr,中值+1,结束);
合并(arr、开始、中间、结束);
}
}
无效合并(整数*arr、整数开始、整数中间值、整数结束){
int i=开始;int j=中值+1;
整数拷贝[end+1];
int-cIndex=0;

虽然(i现在代码是可见的,但很容易看出您确实在破坏堆栈,正如我在我的许多文章中所建议的那样

merge()
中,您有:

int copy[end+1];
以及在
intSortTest()
中具有:

int arr[i];
其中
i
达到1000000

end
为1000000时-它是从
i
设置的-您有一个一百万
int
值的数组正在排序,还有一个包含一百万
int
值的副本(加1),因此您尝试在堆栈上放置200万个4字节
int
值,800000字节超出了堆栈限制。因为800000字节(以前的大小)在Unix和Windows中都适用于堆栈,您使用的是哪一个还不是100%清楚。在Unix/Linux上没有太大的错误余地;Windows上的限制被彻底打破了,因为堆栈上没有4 MB的阵列


建议的修复方法是使用动态内存分配(
malloc()
等)而不是堆栈分配-在排序测试函数和主
merge()
代码中都是如此。

现在代码已经可见,很容易看出您确实在破坏堆栈,正如我在我的一篇文章中所建议的那样

merge()
中,您有:

int copy[end+1];
以及在
intSortTest()
中具有:

int arr[i];
其中
i
达到1000000

end
为1000000时-它是从
i
设置的-您有一个一百万
int
值的数组正在排序,还有一个包含一百万
int
值的副本(加1),因此您尝试在堆栈上放置200万个4字节
int
值,800000字节超出了堆栈限制。因为800000字节(以前的大小)在Unix和Windows中都适用于堆栈,您使用的是哪一个还不是100%清楚。在Unix/Linux上没有太大的错误余地;Windows上的限制被彻底打破了,因为堆栈上没有4 MB的阵列


建议的修复方法是使用动态内存分配(
malloc()
等)而不是堆栈分配-在排序测试函数和主
merge()
代码中。

这是因为您正在堆栈上分配数组。请尝试以下代码

void intSortTest(){
    initSeed();
    for(size_t i = MIN;i <= MAX;i *=10){
        int *arr = malloc(i*sizeof(int));  // <-- changed this
        for(size_t j = 0; j < i;j++){
            arr[j] = rand();
        }
        // sorting the array
        mergesort(arr,0,i);
        // checking if sorted array hold the 
        // condition i[0] <= i[1] ... <= i[n].
        for(size_t j = 1;j < i;j++){
            int *e1 = &arr[j-1];
            int *e2 = &arr[j];
            assert(cmpInt(e2,e1) <= 0);
        }
        printf("INT TEST : %7d\tPASSED\n",i);
        free(arr);   // <-- added this
    }
    printf("\n");
}
合并功能如下所示:

void merge(int *arr,int start,int median,int end){
    int i = start; int j = median;
    int *copy = malloc((end-start)*sizeof(int)); // use malloc for huge arrays
    int cIndex = 0;

    while(i < median && j < end) {  // not i <= median && j <= end
        if(arr[j] <= arr[i]){
            copy[cIndex++] = arr[j++];
        } else {
            copy[cIndex++] = arr[i++];
        }
    }

    while(i < median){ // not i <= median
        copy[cIndex++] = arr[i++];
    }
    while(j < end){  // not j <= median
        copy[cIndex++] = arr[j++];
    }
    for(int k = 0; k < cIndex; k++){
        arr[start++] = copy[k];
    }
    free(copy);
}
void合并(int*arr、int-start、int-median、int-end){
int i=开始;int j=中间值;
int*copy=malloc((结束-开始)*sizeof(int));//对大型数组使用malloc
int-cIndex=0;

而(i
void intSortTest(){
    initSeed();
    for(size_t i = MIN;i <= MAX;i *=10){
        int *arr = malloc(i*sizeof(int));  // <-- changed this
        for(size_t j = 0; j < i;j++){
            arr[j] = rand();
        }
        // sorting the array
        mergesort(arr,0,i);
        // checking if sorted array hold the 
        // condition i[0] <= i[1] ... <= i[n].
        for(size_t j = 1;j < i;j++){
            int *e1 = &arr[j-1];
            int *e2 = &arr[j];
            assert(cmpInt(e2,e1) <= 0);
        }
        printf("INT TEST : %7d\tPASSED\n",i);
        free(arr);   // <-- added this
    }
    printf("\n");
}
合并功能如下所示:

void merge(int *arr,int start,int median,int end){
    int i = start; int j = median;
    int *copy = malloc((end-start)*sizeof(int)); // use malloc for huge arrays
    int cIndex = 0;

    while(i < median && j < end) {  // not i <= median && j <= end
        if(arr[j] <= arr[i]){
            copy[cIndex++] = arr[j++];
        } else {
            copy[cIndex++] = arr[i++];
        }
    }

    while(i < median){ // not i <= median
        copy[cIndex++] = arr[i++];
    }
    while(j < end){  // not j <= median
        copy[cIndex++] = arr[j++];
    }
    for(int k = 0; k < cIndex; k++){
        arr[start++] = copy[k];
    }
    free(copy);
}
void合并(int*arr、int-start、int-median、int-end){
int i=开始;int j=中间值;
int*copy=malloc((结束-开始)*sizeof(int));//对大型数组使用malloc
int-cIndex=0;

而(ivoid initSeed()等声明)
sort\u test.h
中的
不是原型-您需要
void initSeed(void);
将其嵌入原型)。此外,嵌入
main()
merge\u sort.c
中的
是一个相当严重的错误;如果它不在自己的文件中,则应该在
sort\u test.c
中。您不能在任何其他程序中使用
merge\u sort.c
main()
一起。请注意,MCVE()(或MRE或现在使用的任何名称)或SSCCE()不包括与
double
类型相关的代码-您眼前的问题是
int
代码,而不是
double
代码。很可能是堆栈溢出,试图在堆栈上分配太多数组。如果您在Windows上,默认堆栈大小为1 MiB;在类似Unix的系统上,它通常为8MiB。听起来你是在一个类似Unix的系统上,两次分配了100万个4字节整数,从而毁掉了你的堆栈。添加到@JonathanLeffler的注释中,尝试动态分配数组。现在问题是自包含的。它不是最小的,因为你仍然有“双代码”,这与你的系统无关问题,但它应该可以在足够宽松的编译器选项下编译(请注意,
sort\u test.h
中的
void initSeed();
等声明不是原型-您需要
void initSeed()(
void merge(int *arr,int start,int median,int end){
    int i = start; int j = median;
    int *copy = malloc((end-start)*sizeof(int)); // use malloc for huge arrays
    int cIndex = 0;

    while(i < median && j < end) {  // not i <= median && j <= end
        if(arr[j] <= arr[i]){
            copy[cIndex++] = arr[j++];
        } else {
            copy[cIndex++] = arr[i++];
        }
    }

    while(i < median){ // not i <= median
        copy[cIndex++] = arr[i++];
    }
    while(j < end){  // not j <= median
        copy[cIndex++] = arr[j++];
    }
    for(int k = 0; k < cIndex; k++){
        arr[start++] = copy[k];
    }
    free(copy);
}