Почему в отчете памяти Visual Studio CRT отображаются блоки CRT

Я практикую использование библиотеки CRT, чтобы найти утечки памяти. Я написал такой код:

#define _CRTDBG_MAP_ALLOC
#include <stdio.h>
#include <stdlib.h>
#include <crtdbg.h>

typedef struct NodeLL {
    int value;
    struct NodeLL *next;
} Node;

void printLL(Node *pHead) {
    int i=0;
    while(pHead) {
        printf("%d\n", pHead->value);
        i++;
        pHead = pHead->next;
    }
}

Node * addNode(Node *pHead, int value) {
    Node *pNew, *pLL;
    pNew = (Node *)malloc(sizeof(Node));
    pNew->value = value;
    pNew->next = NULL;
    if(!pHead) {
        pHead = pNew;
    }
    else {
        pLL = pHead;
        while(pLL->next) 
            pLL = pLL->next;
        pLL->next = pNew;
    }

    return pHead;
}

void deleteNodes(Node *pHead) {
    Node *pLL;
    int i=0;
    while(pHead) {
        printf("deleting node %d, value is %d\n", i, pHead->value); 
        i++;
        pLL = pHead->next;
        free(pHead);
        pHead = pLL;
    }
}


Node * removeDups(Node *pHead) {
    if (!pHead)
        return NULL;
    Node *pNode2, *pPrev;
    Node *pNode = pHead;
    while(pNode) {
        pPrev = pNode;
        pNode2 = pNode->next; 
        while(pNode2) {
            if(pNode2->value == pNode->value) {
                pPrev->next = pNode2->next;
                free(pNode2);
                pNode2 = pPrev->next;
            }
            else {
                pPrev = pNode2;
                pNode2 = pNode2->next;
            }
        }
        pNode = pNode->next;
    }
    return pHead;
}

int main() {

    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
    //_CrtSetBreakAlloc(71);   // used to break at the second malloc

    _CrtMemState s1, s2, s3;

    // take a snap shot of memory before allocating memory
    _CrtMemCheckpoint(&s1);

    int NodeNum, i, j, value;
    Node *pHead = NULL;

    printf("How many nodes in the linked list?");
    scanf("%d", &NodeNum); 
    for (i=0; i<NodeNum; i++) {
        printf("Please enter Node %d value:", i);
        scanf("%d", &value);
        pHead = addNode(pHead, value);
    }


    printLL(pHead);
    printf("remove duplicates\n");
    pHead = removeDups(pHead);
    printLL(pHead);
    // clean up
    //deleteNodes(pHead);

    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
    _CrtDumpMemoryLeaks();


    // take a snap shot of memory after allocating memory
    _CrtMemCheckpoint(&s2);

    if(_CrtMemDifference(&s3, &s1, &s2) ) 
        _CrtMemDumpStatistics(&s3);

    return 0;
}

Я получаю следующий вывод:

Detected memory leaks!

Dumping objects -> ...

\2_1_removedupll\removedupsll.cpp(23) : {72} normal block at 0x00701570, 8 bytes long.
 Data: <        > 03 00 00 00 00 00 00 00 

\2_1_removedupll\removedupsll.cpp(23) : {71} normal block at 0x00701528, 8 bytes long.
 Data: <    p p > 02 00 00 00 70 15 70 00 

\2_1_removedupll\removedupsll.cpp(23) : {70} normal block at 0x007014E0, 8 bytes long.
 Data: <    ( p > 01 00 00 00 28 15 70 00 

Object dump complete.

0 bytes in 0 Free Blocks.

24 bytes in 3 Normal Blocks.

*4096 bytes in 1 CRT Blocks.*

0 bytes in 0 Ignore Blocks.

0 bytes in 0 Client Blocks.

Largest number used: 3870 bytes.

Total allocations: 4120 bytes.

Он обнаружил протекшие 24 байта обычных блоков. Я ожидал этого. Но что это за 4096 байт в 1 ЭЛТ-блоках? По словам Microsoft:

Блок CRT выделяется библиотекой CRT для собственного использования. Библиотека CRT обрабатывает освобождение для этих блоков. Поэтому маловероятно, что вы увидите их в отчете об утечке памяти, если что-то не так, например, библиотека CRT повреждена.

Должен ли я просто игнорировать эти 4096 байтов? Благодарю.

3 ответа

Это распределение 4,096 байт является временным буфером для stdout, который выделяется при первом звонке printf, Потому что вы сначала позвоните printf находится между вашими двумя контрольными точками памяти, это выглядит как разница между двумя контрольными точками. Если вы добавите звонок в printf до вашей первой контрольной точки памяти, это распределение 4,096 байт не появится в разнице.

Этот буфер освобождается, когда CRT завершается нормально.

Кажется, действительно есть некоторые утечки. Я проверил ваш код с Deleaker и посмотрите, что у меня есть:

утечки

ссылка на изображение

Также, если я ставлю точку останова на строку с free (), я никогда не попаду туда в случае ввода двух одинаковых значений.

Если я ввожу два разных значения, я нажимаю free () один раз (в функции removeDups()). Только однажды.

Очевидно, что-то не так с кодом! Вам не нужно вызывать deleteNodes() в конце концов?

Да, блоки ЭЛТ можно безопасно игнорировать. Выделение не было выполнено вашим кодом, поэтому вам не нужно беспокоиться об этом

Другие вопросы по тегам