Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么Visual Studio CRT内存报告显示CRT块_C++_Visual Studio_Memory Leaks_Crt - Fatal编程技术网

C++ 为什么Visual Studio CRT内存报告显示CRT块

C++ 为什么Visual Studio CRT内存报告显示CRT块,c++,visual-studio,memory-leaks,crt,C++,Visual Studio,Memory Leaks,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;

我正在练习使用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;
}
\define\u CRTDBG\u MAP\u ALLOC
#包括
#包括
#包括
类型定义结构节点{
int值;
结构NodeLL*next;
}节点;
void printl(节点*pHead){
int i=0;
while(pHead){
printf(“%d\n”,pHead->value);
i++;
pHead=pHead->next;
}
}
Node*addNode(Node*pHead,int值){
节点*pNew,*pLL;
pNew=(Node*)malloc(sizeof(Node));
pNew->value=value;
pNew->next=NULL;
如果(!pHead){
pHead=pNew;
}
否则{
pLL=pHead;
同时(pLL->next)
pLL=pLL->next;
pLL->next=pNew;
}
返回pHead;
}
void deleteNodes(节点*pHead){
节点*pLL;
int i=0;
while(pHead){
printf(“删除节点%d,值为%d\n”,i,pHead->value);
i++;
pLL=pHead->next;
免费(pHead);
pHead=pLL;
}
}
节点*removeDups(节点*pHead){
如果(!pHead)
返回NULL;
节点*pNode2,*pPrev;
Node*pNode=pHead;
while(pNode){
pPrev=pNode;
pNode2=pNode->next;
while(pNode2){
如果(pNode2->value==pNode->value){
pPrev->next=pNode2->next;
免费(pNode2);
pNode2=pPrev->next;
}
否则{
pPrev=pNode2;
pNode2=pNode2->next;
}
}
pNode=pNode->next;
}
返回pHead;
}
int main(){
_CRT报告模式(CRT错误,CRTDBG模式调试);
//_CrtSetBreakAlloc(71);//用于在第二个malloc处断开
_CRTMEMS1、s2、s3状态;
//在分配内存之前拍摄内存快照
_CrtMemCheckpoint(&s1);
int NodeNum,i,j,value;
Node*pHead=NULL;
printf(“链表中有多少节点?”);
scanf(“%d”、&NodeNum);
对于(i=0;i。。。
\2_1 _removedupll\removedupsll.cpp(23):0x00701570处的{72}正常块,8字节长。
数据:<>03 00 00
\2_1 _removedupll\removedupsll.cpp(23):0x00701528处的{71}正常块,8字节长。
数据:02 00 00 70 15 70 00
\2_1 _removedupll\removedupsll.cpp(23):0x007014E0处的{70}正常块,8字节长。
数据:<(p>01 00 00 28 15 70 00
对象转储完成。
0个空闲块中有0个字节。
3个普通块中有24个字节。
*1个CRT块中有4096个字节*
0个忽略块中有0个字节。
0个客户端块中有0个字节。
使用的最大数字:3870字节。
总分配:4120字节。
它发现了泄漏的24字节普通块。我预料到了。但这是什么?根据微软的说法:

CRT块由CRT库分配供自己使用。CRT库处理这些块的解除分配。因此,除非出现严重错误,例如CRT库已损坏,否则不太可能在内存泄漏报告中看到这些块


我应该忽略这个4096字节吗?谢谢。

是的,CRT块可以安全地忽略。分配不是由您的代码完成的,所以您不必为此费心。

似乎确实存在一些泄漏。我已检查了您的代码,并查看我的代码:

另外,如果我在free()的行中放置断点,在输入两个相同值的情况下,我将永远不会命中断点

如果我输入两个不同的值,我会在removeDups()函数中点击free()一次。只点击一次


显然代码出了问题!您不需要调用deleteNodes()吗最后?

这个4096字节的分配是
stdout
的临时缓冲区,它是在您第一次调用
printf
时分配的。因为您第一次调用
printf
是在两个内存检查点之间,它显示为两个检查点之间的差异。如果您在第一个内存检查点,此4096字节分配将不会出现差异


当CRT正常终止时,此缓冲区将被释放。

谢谢。我没有足够的声誉来提升它。嗨,阿泰姆,谢谢你帮我检查它。是的,有泄漏。我故意没有释放列表以查看内存泄漏检查的工作方式。我不知道我是否应该担心4096个CRT块。就像Anrsimha下面说的,我可以忽略它,因为它是由visual studio管理的。@Amber,不!你不能。这是一个真正的泄漏,你必须释放内存。当然,在这样简单的项目中,这可能不是一个大问题,但在真正的项目中,内存泄漏是一个大问题:内存不足,应用程序崩溃:)