C++ 为什么Visual Studio CRT内存报告显示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;
#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,不!你不能。这是一个真正的泄漏,你必须释放内存。当然,在这样简单的项目中,这可能不是一个大问题,但在真正的项目中,内存泄漏是一个大问题:内存不足,应用程序崩溃:)