_CrtSetDbgFlag
Pobiera lub modyfikuje stan _crtDbgFlag
flagi w celu kontrolowania zachowania alokacji menedżera sterty debugowania (tylko wersja debugowania).
Składnia
int _CrtSetDbgFlag(
int newFlag
);
Parametry
newFlag
Nowy stan dla elementu _crtDbgFlag
.
Wartość zwracana
Zwraca poprzedni stan ._crtDbgFlag
Uwagi
Funkcja _CrtSetDbgFlag
umożliwia aplikacji kontrolowanie sposobu, w jaki menedżer sterty debugowania śledzi alokacje pamięci, modyfikując pola bitów flagi _crtDbgFlag
. Ustawiając pola bitowe, aplikacja może poinstruować menedżera stert debugowania, aby wykonać specjalne operacje debugowania. Istnieje kilka możliwych operacji:
- Sprawdzanie przecieków pamięci podczas zamykania aplikacji i raportowania, czy istnieją,
- Symulowanie warunków z małą ilością pamięci przez określenie, że wolne bloki pamięci powinny pozostać na liście połączonych sterty,
- Weryfikowanie integralności sterty przez sprawdzenie każdego bloku pamięci przy każdym żądaniu alokacji.
Gdy _DEBUG
nie jest zdefiniowana, wywołania do _CrtSetDbgFlag
są usuwane podczas przetwarzania wstępnego.
W poniższej tabeli wymieniono pola bitowe i _crtDbgFlag
opisano ich zachowanie. Ponieważ ustawienie bitów powoduje zwiększenie danych wyjściowych diagnostycznych i zmniejszoną szybkość wykonywania programu, te bity nie są domyślnie ustawione (wyłączone). Aby uzyskać więcej informacji na temat tych pól bitów, zobacz Funkcje raportowania stanu stert.
Pole bitowe | Domyślny | opis |
---|---|---|
_CRTDBG_ALLOC_MEM_DF |
ON | WŁĄCZONE: Włącz alokacje sterty debugowania i użyj identyfikatorów typu bloku pamięci, takich jak _CLIENT_BLOCK . OFF: Dodaj nowe alokacje do listy połączonej sterty, ale ustaw typ bloku na _IGNORE_BLOCK .Można również połączyć z dowolnymi makrami sprawdzania częstotliwości stertów. |
_CRTDBG_CHECK_ALWAYS_DF |
WYŁ. | WŁ.: Wywołaj _CrtCheckMemory każde żądanie alokacji i cofnięcia przydziału. OFF: _CrtCheckMemory należy wywołać jawnie.Makra sprawdzania częstotliwości stertowania nie mają wpływu, gdy ta flaga jest ustawiona. |
_CRTDBG_CHECK_CRT_DF |
WYŁ. | WŁĄCZONE: Uwzględnij _CRT_BLOCK typy w operacjach wykrywania przecieków i różnic stanu pamięci. OFF: pamięć używana wewnętrznie przez bibliotekę czasu wykonywania jest ignorowana przez te operacje.Można również połączyć z dowolnymi makrami sprawdzania częstotliwości stertów. |
_CRTDBG_DELAY_FREE_MEM_DF |
WYŁ. | WŁĄCZONE: Zachowaj wolne bloki pamięci na liście połączonej sterty, przypisz im typ i wypełnij je _FREE_BLOCK wartością bajtu 0xDD. OFF: Nie należy utrzymywać wolnych bloków na liście połączonych sterty.Można również połączyć z dowolnymi makrami sprawdzania częstotliwości stertów. |
_CRTDBG_LEAK_CHECK_DF |
WYŁ. | WŁĄCZONE: Przeprowadź automatyczne sprawdzanie przecieków podczas zamykania programu za pośrednictwem wywołania _CrtDumpMemoryLeaks i wygeneruj raport o błędach, jeśli aplikacja nie zwolni całej przydzielonej pamięci. OFF: Nie wykonuj automatycznego sprawdzania przecieków podczas zamykania programu.Można również połączyć z dowolnymi makrami sprawdzania częstotliwości stertów. |
Makra częstotliwości sprawdzania stert
Możesz określić, jak często biblioteka czasu wykonywania języka C wykonuje walidację sterta debugowania (_CrtCheckMemory
) na podstawie liczby wywołań do malloc
, , realloc
free
i _msize
.
_CrtSetDbgFlag
Następnie sprawdza górne 16 bitów parametru newFlag
dla wartości. Określona wartość to liczba malloc
wywołań , realloc
, free
i _msize
między wywołaniami _CrtCheckMemory
. W tym celu udostępniono cztery wstępnie zdefiniowane makra.
Makro | malloc Liczba wywołań , realloc , free i _msize między wywołaniami_CrtCheckMemory |
---|---|
_CRTDBG_CHECK_EVERY_16_DF |
16 |
_CRTDBG_CHECK_EVERY_128_DF |
128 |
_CRTDBG_CHECK_EVERY_1024_DF |
1024 |
_CRTDBG_CHECK_DEFAULT_DF |
0 (domyślnie bez sprawdzania stert) |
Domyślnie _CrtCheckMemory
nie jest wywoływana podczas operacji pamięci. Możesz to zmienić, wysyłając flagi wyświetlane powyżej do _CrtSetDbgFlag()
.
Na przykład można określić stertę sprawdzaną co 16 malloc
, realloc
, free
i _msize
operacji przy użyciu następującego kodu:
#include <crtdbg.h>
int main( )
{
int tmp;
// Get the current bits
tmp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
// Clear the upper 16 bits and OR in the desired frequency
tmp = (tmp & 0x0000FFFF) | _CRTDBG_CHECK_EVERY_16_DF;
// Set the new bits
_CrtSetDbgFlag(tmp);
}
Górne 16 bitów parametru są ignorowane po _CRTDBG_CHECK_ALWAYS_DF
określeniunewFlag
. W takim przypadku jest wywoływana za każdym razem, _CrtCheckMemory
gdy wywołujesz metodę malloc
, , realloc
free
i _msize
.
newFlag
to nowy stan, który ma być stosowany do _crtDbgFlag
elementu i jest kombinacją wartości dla każdego pola bitowego.
Aby zmienić co najmniej jedno z tych pól bitowych i utworzyć nowy stan flagi
newFlag
Wywołaj metodę_CrtSetDbgFlag
o wartości równej, aby_CRTDBG_REPORT_FLAG
uzyskać bieżący_crtDbgFlag
stan i zapisać zwracaną wartość w zmiennej tymczasowej.Włącz wszystkie bity za pomocą bitowego znaku "lub" (
|
) zmiennej tymczasowej z odpowiednimi maskami bitów (reprezentowanymi w kodzie aplikacji przez stałe manifestu).Wyłącz inne bity z bitowym znakiem "and" (
&
) zmiennej z bitowym znakiem "not" (~
) odpowiednich masek bitów.Wywołaj metodę
_CrtSetDbgFlag
onewFlag
wartości równej wartości przechowywanej w zmiennej tymczasowej, aby ustawić nowy stan dla_crtDbgFlag
elementu .
Poniższy kod pokazuje, jak symulować warunki z małą ilością pamięci, utrzymując wolne bloki pamięci na liście połączonej sterty i uniemożliwiając _CrtCheckMemory
wywoływanie przy każdym żądaniu alokacji:
// Get the current state of the flag
// and store it in a temporary variable
int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
// Turn On (OR) - Keep freed memory blocks in the
// heap's linked list and mark them as freed
tmpFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
// Turn Off (AND) - prevent _CrtCheckMemory from
// being called at every allocation request
tmpFlag &= ~_CRTDBG_CHECK_ALWAYS_DF;
// Set the new state for the flag
_CrtSetDbgFlag( tmpFlag );
Aby zapoznać się z omówieniem zarządzania pamięcią i sterty debugowania, zobacz szczegóły sterty debugowania CRT.
Aby wyłączyć flagę z _CrtSetDbgFlag
funkcją, użyj bitowego znaku "i" (&
) zmiennej z bitowym znakiem "not" (~
) maski bitowej.
Jeśli newFlag
nie jest prawidłową wartością, ta funkcja wywołuje nieprawidłową procedurę obsługi parametrów zgodnie z opisem w temacie Weryfikacja parametrów. Jeśli wykonanie może kontynuować, ta funkcja ustawia errno
EINVAL
wartość i zwraca poprzedni stan _crtDbgFlag
.
Wymagania
Procedura | Wymagany nagłówek |
---|---|
_CrtSetDbgFlag |
<crtdbg.h> |
Aby uzyskać więcej informacji o zgodności, zobacz Zgodność.
Biblioteki
Debugowanie tylko wersji bibliotek czasu wykonywania języka C.
Przykład
// crt_crtsetdflag.c
// compile with: /c -D_DEBUG /MTd -Od -Zi -W3 /link -verbose:lib /debug
// This program concentrates on allocating and freeing memory
// blocks to test the functionality of the _crtDbgFlag flag.
#include <string.h>
#include <malloc.h>
#include <crtdbg.h>
int main( )
{
char *p1, *p2;
int tmpDbgFlag;
_CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
_CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDERR );
// Set the debug-heap flag to keep freed blocks in the
// heap's linked list - This will allow us to catch any
// inadvertent use of freed memory
tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF;
tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(tmpDbgFlag);
// Allocate 2 memory blocks and store a string in each
p1 = malloc( 34 );
p2 = malloc( 38 );
strcpy_s( p1, 34, "p1 points to a Normal allocation block" );
strcpy_s( p2, 38, "p2 points to a Client allocation block" );
// Free both memory blocks
free( p2 );
free( p1 );
// Set the debug-heap flag to no longer keep freed blocks in the
// heap's linked list and turn on Debug type allocations (CLIENT)
tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
tmpDbgFlag |= _CRTDBG_ALLOC_MEM_DF;
tmpDbgFlag &= ~_CRTDBG_DELAY_FREE_MEM_DF;
_CrtSetDbgFlag(tmpDbgFlag);
// Explicitly call _malloc_dbg to obtain the filename and
// line number of our allocation request and also so we can
// allocate CLIENT type blocks specifically for tracking
p1 = _malloc_dbg( 40, _NORMAL_BLOCK, __FILE__, __LINE__ );
p2 = _malloc_dbg( 40, _CLIENT_BLOCK, __FILE__, __LINE__ );
strcpy_s( p1, 40, "p1 points to a Normal allocation block" );
strcpy_s( p2, 40, "p2 points to a Client allocation block" );
// _free_dbg must be called to free the CLIENT block
_free_dbg( p2, _CLIENT_BLOCK );
free( p1 );
// Allocate p1 again and then exit - this will leave unfreed
// memory on the heap
p1 = malloc( 10 );
}