【问题标题】:Suggestion for chkstk.asm stackoverflow exception in C++ with Visual Studio使用 Visual Studio 对 C++ 中的 chkstk.asm stackoverflow 异常的建议
【发布时间】:2011-02-19 15:09:36
【问题描述】:

我正在使用合并排序的实现。我正在尝试使用 C++ Visual Studio 2010 (msvc)。但是当我使用一个包含 300000 个整数的数组进行计时时,它显示了一个未处理的 stackoverflow 异常并将我带到一个名为“chkstk.asm”的只读文件。我将大小减小到 200000 并且它起作用了。同样的代码在大小为 400000 的情况下与无 C 的 4 编辑器 (mingw 2.95) 一起工作,没有任何问题。你有什么建议让代码在 Visual Studio 中工作吗?

可能是归并排序中的递归导致了问题。

【问题讨论】:

    标签: c++ visual-studio recursion visual-c++ stack-overflow


    【解决方案1】:

    问题解决了。感谢 Kotti 提供代码。我在与该代码进行比较时遇到了问题。问题不在于过多的递归。实际上,我正在使用存储在堆栈中的普通 C++ 数组。因此问题耗尽了堆栈空间。我只是用 new/delete 语句将它更改为一个动态分配的数组,它就起作用了。

    【讨论】:

    • 这解决了我的问题。谢谢你。 +1
    【解决方案2】:

    我不太确定,但这可能是您实现合并排序的一个特殊问题(导致堆栈溢出)。有很多好的实现(使用google),以下适用于数组大小= 2000000的VS2008。

    (你可以在VS2010中试试)

    #include <cstdlib>
    #include <memory.h>
    
    // Mix two sorted tables in one and split the result into these two tables.
    void Mix(int* tab1, int *tab2, int count1, int count2)
    {
       int i,i1,i2;
       i = i1 = i2 = 0;
       int * temp = (int *)malloc(sizeof(int)*(count1+count2));
    
       while((i1<count1) && (i2<count2))
       {
          while((i1<count1) && (*(tab1+i1)<=*(tab2+i2)))
          {
             *(temp+i++) = *(tab1+i1);
             i1++;
          }
          if (i1<count1)
          {
             while((i2<count2) && (*(tab2+i2)<=*(tab1+i1)))
             {
                *(temp+i++) = *(tab2+i2);
                i2++;
             }
          }
       }
    
       memcpy(temp+i,tab1+i1,(count1-i1)*sizeof(int));
       memcpy(tab1,temp,count1*sizeof(int));
    
       memcpy(temp+i,tab2+i2,(count2-i2)*sizeof(int));
       memcpy(tab2,temp+count1,count2*sizeof(int));
       free(temp);
    }
    
    void MergeSort(int *tab,int count) {
       if (count == 1) return;
    
       MergeSort(tab, count/2);
       MergeSort(tab + count/2, (count + 1) /2);
       Mix(tab, tab + count / 2, count / 2, (count + 1) / 2);
    }
    
    void main() {
       const size_t size = 2000000;
       int* array = (int*)malloc(sizeof(int) * size);
       for (int i = 0; i < size; ++i) {
          array[i] = rand() % 5000;
       }
    
       MergeSort(array, size);
    }
    

    【讨论】:

    • 这段代码在 Visual Studio 2010 中运行没有任何问题。
    • 好吧,我想这意味着您之前的实现在调用递归时填充堆栈方面是无效的。我认为您可以尝试自己确定关键部分或在此处发布您的代码。
    【解决方案3】:

    我的猜测是你有太多的递归,你只是用完了堆栈空间。您可以使用linker's /F command line option 增加您的堆栈大小。但是,如果您不断达到堆栈大小限制,您可能需要从算法中重构递归。

    【讨论】:

      【解决方案4】:

      _chkstk() 指的是“检查堆栈”。默认情况下,这发生在 Windows 中。可以使用/Gs- 选项或分配合理的高大小(如/Gs1000000)来禁用它。另一种方法是使用以下方法禁用此功能:

      #pragma check_stack(off)  // place at top header to cover all the functions
      

      Official documentation.
      Reference.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-07-22
        • 1970-01-01
        • 2014-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多