共用方式為


_resetstkoflw

從堆疊溢位復原。

重要

這個 API 不能用於 Windows 執行階段執行的應用程式。如需詳細資訊,請參閱 CRT 函式不支援使用 /ZW

int _resetstkoflw ( void );

傳回值

非零值,如果函式成功,則為零,如果失敗。

備註

_resetstkoflw 函式可從堆疊溢位的情況中復原,讓程式得以繼續執行,不會因嚴重的例外狀況錯誤而失敗。 如果 _resetstkoflw 未呼叫函式,則不會產生保護分頁在先前例外狀況之後。 下次發生堆疊溢位時,完全不會有例外狀況,且會在沒有產生警告的情況下結束此處理序。

如果在應用程式中的執行緒會產生 EXCEPTION_STACK_OVERFLOW 例外狀況時,執行緒處於損毀狀態把它的堆疊中。 與其他例外狀況要例如 EXCEPTION_ACCESS_VIOLATIONEXCEPTION_INT_DIVIDE_BY_ZERO,這會是,沒有損壞堆疊。 當程式第一次載入時,堆疊設為選擇性地小值。 堆疊然後成長需求調整執行緒的需要。 這是將與 PAGE_GUARD 存取的頁面實作在目前堆疊結尾。 如需詳細資訊,請參閱 會產生保護分頁

當程式碼造成堆疊指標指向這個頁面時的位址,例外狀況會顯示和系統會針對下列三個項目:

  • 移除保護網頁的 PAGE_GUARD 保護,讓執行緒可以寫入記憶體讀取和寫入資料。

  • 配置在最後一個的下一頁的新保護網頁。

  • 重新執行引發例外狀況的指示。

如此一來,系統可以為執行緒自動將堆疊的大小。 處理序中的每個執行緒的堆疊大小上限。 堆疊大小設定在編譯時期由 /STACK (堆疊配置),或是在 .def 檔中的 STACKSIZE 陳述式的專案。

當這個最大堆疊大小會超過時,系統會針對下列三個項目:

  • 移除保護網頁的 PAGE_GUARD 保護,如前所述。

  • 嘗試在最後一個下配置新保護網頁。 不過,,因為最大堆疊大小已超過,這就會失敗。

  • 引發例外狀況,以便執行緒可以處理它在例外狀況區塊。

請注意,此時,堆疊不會產生保護分頁。 下次程式隨時增加到堆疊的末端,應該會產生保護分頁、程式寫入在堆疊結尾並造成存取違規。

呼叫 _resetstkoflw 還原保護網頁,每當在復原堆疊溢位例外狀況後完成。 這個函式可從 __except 區塊或外部的主體內呼叫每個 __except 區塊。 不過,應該使用時,有一些限制在它。 不應該呼叫**_resetstkoflw** 類別:

  • 篩選條件運算式。

  • 篩選函式。

  • 從篩選函式呼叫的函式。

  • catch 區塊。

  • __finally 區塊。

在這些點,堆疊完全不會回溯。

堆疊溢位例外狀況產生,因為結構化例外狀況,而非 C++ 例外狀況,因此, _resetstkoflw 不適用於一般 catch 區塊,因為它不會攔截堆疊溢位例外狀況。 不過,如果 _set_se_translator ,用來實作擲回 C++ 例外狀況的結構化的例外狀況轉譯器 (第二個範例中),堆疊溢位例外狀況產生可由 C ++. catch 區塊處理的 C++. C++ 例外狀況。

呼叫從結構化例外狀況轉譯器函式所擲回的例外狀況到達的 C ++. catch 區塊的 _resetstkoflw 是不安全的。 在這種情況下,堆疊空間不會釋放,且堆疊指標不會重設到 catch 區塊之外,,即使解構函式為在 Catch 區塊之前的所有可終結的物件呼叫。 不應該呼叫這個函式,直到堆疊空間被釋放,且堆疊指標重設。 因此,應該在離開 catch 區塊之後呼叫它。 當為可能的 ACE 堆疊空間應該在 catch 區塊,因為在 catch 區塊本身就會嘗試從先前堆疊溢位的復原堆疊溢位 (Stack Overflow) 不是可復原的,而且可能造成程式停止回應,而在 catch 區塊的溢位觸發本身同一個 catch 區塊處理的例外狀況。

_resetstkoflw 在正確的位置可能會失敗的情況,即使使用,例如內 __except 區塊。 如果,在回溯堆疊後,仍有不保留足夠的堆疊空間執行 _resetstkoflw 不寫入堆疊的最後一頁, _resetstkoflw 不會重設堆疊的最後一頁,因為保護網頁並傳回 0,表示失敗。 因此,這個函式的使用方式應該包括檢查傳回值而非假設,堆疊是安全使用。

結構化例外處理 (Exception Handling) 將不會攔截 STATUS_STACK_OVERFLOW 例外狀況,在編譯應用程式與 /clr 或 /clr:pure (請參閱 /clr (Common Language Runtime 編譯))。

需求

程序

必要的標頭檔

_resetstkoflw

<malloc.h>

如需詳細資訊,請參閱介紹中的 相容性

程式庫:CRT 程式庫功能的所有版本。

範例

以下範例說明 _resetstkoflw 函式的建議的使用方式。

// crt_resetstkoflw.c
// Launch program with and without arguments to observe
// the difference made by calling _resetstkoflw.

#include <malloc.h>
#include <stdio.h>
#include <windows.h>

void recursive(int recurse)
{
   _alloca(2000);
   if (recurse)
      recursive(recurse);
}

// Filter for the stack overflow exception.
// This function traps the stack overflow exception, but passes
// all other exceptions through. 
int stack_overflow_exception_filter(int exception_code)
{
   if (exception_code == EXCEPTION_STACK_OVERFLOW)
   {
       // Do not call _resetstkoflw here, because
       // at this point, the stack is not yet unwound.
       // Instead, signal that the handler (the __except block)
       // is to be executed.
       return EXCEPTION_EXECUTE_HANDLER;
   }
   else
       return EXCEPTION_CONTINUE_SEARCH;
}

int main(int ac)
{
   int i = 0;
   int recurse = 1, result = 0;

   for (i = 0 ; i < 10 ; i++)
   {
      printf("loop #%d\n", i + 1);
      __try
      {
         recursive(recurse);

      }

      __except(stack_overflow_exception_filter(GetExceptionCode()))
      {
         // Here, it is safe to reset the stack.

         if (ac >= 2)
         {
            puts("resetting stack overflow");
            result = _resetstkoflw();
         }
      }

      // Terminate if _resetstkoflw failed (returned 0)
      if (!result)
         return 3;
   }

   return 0;
}

範例輸出

沒有程式引數:

loop #1

程式停止回應,而不執行進一步的反覆項目。

程式引數:

loop #1
resetting stack overflow
loop #2
resetting stack overflow
loop #3
resetting stack overflow
loop #4
resetting stack overflow
loop #5
resetting stack overflow
loop #6
resetting stack overflow
loop #7
resetting stack overflow
loop #8
resetting stack overflow
loop #9
resetting stack overflow
loop #10
resetting stack overflow

89f73td2.collapse_all(zh-tw,VS.110).gif描述

下列範例在結構化例外狀況轉換成 C++ 例外狀況的程式顯示對 _resetstkoflw 的建議用法。

89f73td2.collapse_all(zh-tw,VS.110).gif程式碼

// crt_resetstkoflw2.cpp
// compile with: /EHa
// _set_se_translator requires the use of /EHa
#include <malloc.h>
#include <stdio.h>
#include <windows.h>
#include <eh.h>

class Exception { };

class StackOverflowException : Exception { };

// Because the overflow is deliberate, disable the warning that
// this function will cause a stack overflow.
#pragma warning (disable: 4717)
void CauseStackOverflow (int i)
{
        // Overflow the stack by allocating a large stack-based array
        // in a recursive function.
        int a[10000];
        printf("%d ", i);
        CauseStackOverflow (i + 1);
}

void __cdecl SEHTranslator (unsigned int code, _EXCEPTION_POINTERS*)
{
   // For stack overflow exceptions, throw our own C++ 
   // exception object.
   // For all other exceptions, throw a generic exception object.
   // Use minimal stack space in this function.
   // Do not call _resetstkoflw in this function.

   if (code == EXCEPTION_STACK_OVERFLOW)
      throw StackOverflowException ( );
   else
      throw Exception( );
}

int main ( )
{
        bool stack_reset = false;
        bool result = false;

        // Set up a function to handle all structured exceptions,
        // including stack overflow exceptions.
        _set_se_translator (SEHTranslator);

        try
        {
            CauseStackOverflow (0);
        }
        catch (StackOverflowException except)
        {
                // Use minimal stack space here.
                // Do not call _resetstkoflw here.
                printf("\nStack overflow!\n");
                stack_reset = true;
        }
        catch (Exception except)
        {
                // Do not call _resetstkoflw here.
                printf("\nUnknown Exception!\n");
        }
        if (stack_reset)
        {
          result = _resetstkoflw();
          // If stack reset failed, terminate the application.
          if (result == 0)
             exit(1);
        }

        void* pv = _alloca(100000);
        printf("Recovered from stack overflow and allocated 100,000 bytes"
               " using _alloca.");

   return 0;
}

範例輸出

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
Stack overflow!
Recovered from stack overflow and allocated 100,000 bytes using _alloca.

.NET Framework 對等用法

不適用。若要呼叫標準 C 函式,請使用 PInvoke。如需更多的資訊,請參閱 Platform Invoke Examples

請參閱

參考

_alloca