一个很简单的程序,可是不对.求好心人教教我

时间:2021-06-02 09:30:40
我用的vc6.0
其实这个程序不干什么正经事,就是想在每次new和delete时告诉我下该行代码所在位置和
是第几次new或delete,可是不对.请好心人教教我

#include <iostream>
using namespace std;

inline void * operator new (size_t nSize, const char * file, int line)

    static count = 0;
         count++;
    cout << "file: " << file << " line: " << line << endl;
    cout << "the " << count << " allocation" << endl;
    return malloc(nSize);
}

inline void operator delete (void * ptr)

    static count = 0;
    count++;
    cout << "the " << count << " deallocation" << endl;
    free(ptr);

}

void main()
{
         int *p = new(__FILE__, __LINE__) int(6);
    int *p2 = new(__FILE__, __LINE__) int(8);
    cout << *p << endl;
    cout << *p2 << endl;
         delete p;
         delete p2;
}

22 个解决方案

#1


请高手们指正一下谢谢

#2


改为
#include <iostream>
#include <stdlib.h>
using namespace std;

inline void * operator new (size_t nSize, const char * file, int line)

    static count = 0;
         count++;
 printf("file:%s  line:%d",file,line);
 printf("\nthe %d allocation\n",count);
    return malloc(nSize);
}

inline void operator delete (void * ptr)

    static count = 0;
    count++;
 printf("\n the %d delete",count);
    free(ptr);

}

void main()
{
         int *p = new(__FILE__, __LINE__) int(6);
    int *p2 = new(__FILE__, __LINE__) int(8);
    cout << *p << endl;
    cout << *p2 << endl;
         delete p;
         delete p2;
}


cout内部会调用delete ...死循环

#3


cout内部会调用delete ...
楼上的,为什么cout会调用delete呢?

#4


谢谢您,您说得很对.我的new和delete覆盖掉了全局的new和delete后,我就发现了cout根本不能再输出int型变量,但您能具体说明原因吗?在我的程序中,删除delete函数中的第三行又能运行了.所以我想知道它深层的原因

#5


我哪知道?
反正debug的时候发现了就是了
C++标准库内部用的东西你是无法预测的.

顺便说一下,在全局变量的构造函数中也不要调用cout之类,因为它们可能还没初始化.

#6


我debug时,只是发现到了cout那行就会死机,我也是改成您这样去解决的。不过我没看出是由于delete会造成死循环的问题,您能教教我您是怎么看出来的吗?

#7


而且我在一个函数的静态对象的析构函数里调用cout输出也会有问题,可能就是您说的另一个问题了

#8


new delete 本来就是很常用的操作。运算符重载,或者替换一些常用函数,应该尽量做的简单,最好不要引用库函数。你可以只记录行号,或者增加计数,在外面打印。如果你怕不出问题,那不如在这些函数中调用什么messagebox之类的,保证你跟踪都跟不完。

#9


vc debug 的时候总会抛出异常吧,然后可以看到调用栈么-_-

main函数结束以后也不要调用cout,因为cout可能已经析购了.

#10


KeepRun(VOID) :其实我程序的原意是重载new和delete,对内存分配用链表记录,这样可以检测内存泄漏。只是问问题时为了简单删除了大部分。
谢谢您。请教您下如果您要检测内存泄漏,会怎么做?谢谢!

#11


你可以考虑class中自定的new,delete
这样就不用操心这么多了.

#12


yjh1982(血精灵):我也这么做了,这样就是不能发现如
int * p = new int(5)
这样的内存泄露,因为它是基本类型,所以我才重写全局的new和delete的

#13


原因就是你重载了全局的new操作,这就出现问题了

cout << "file: " << file << " line: " << line << endl;

在上面的这行操作中当输出 line时 cout 又调用了 new操作(你重载后的),
这样就陷入了死循环

#14


对于你想发现内存泄露的问题,你可以这样解决:
之所以出现死循环,是由于在cout中调用了delete,
所以你可以仅在你重载的new和delete中实现引用计数,并进行
相应的一定判断,如看两个的引用记数是否相等等操作,
而不要调用cout库函数,
而可以另写一个仅用于输出的函数OutputCount()中调用cout,
当且仅当你的引用记数满足内存泄露的条件时,你才调用你
的OutputCount()函数打印输出结果,
我觉的也能实现跟踪的效果吧,
这样应该不会出问题。

#15


// ^_^ 果真是调用delete 陷入死循环

#16


想问一下血精灵是怎么debug出来的,长见识了!

cout->delete->cout...

#17


按F5 debug调试,出异常时会停在某个位置.
就可以看到函数调用栈了

#18


我想问一下,void * 是代表什么?

#19


一个空指针,指向什么都可以,不过要赋值的时候要强制转换。

#20


纠正以下哈
void*            空类型指针
char* p = NULL;  空指针

#21


谢谢大家了

#22


听君一席话、胜读十年书!
谢谢大家!

#1


请高手们指正一下谢谢

#2


改为
#include <iostream>
#include <stdlib.h>
using namespace std;

inline void * operator new (size_t nSize, const char * file, int line)

    static count = 0;
         count++;
 printf("file:%s  line:%d",file,line);
 printf("\nthe %d allocation\n",count);
    return malloc(nSize);
}

inline void operator delete (void * ptr)

    static count = 0;
    count++;
 printf("\n the %d delete",count);
    free(ptr);

}

void main()
{
         int *p = new(__FILE__, __LINE__) int(6);
    int *p2 = new(__FILE__, __LINE__) int(8);
    cout << *p << endl;
    cout << *p2 << endl;
         delete p;
         delete p2;
}


cout内部会调用delete ...死循环

#3


cout内部会调用delete ...
楼上的,为什么cout会调用delete呢?

#4


谢谢您,您说得很对.我的new和delete覆盖掉了全局的new和delete后,我就发现了cout根本不能再输出int型变量,但您能具体说明原因吗?在我的程序中,删除delete函数中的第三行又能运行了.所以我想知道它深层的原因

#5


我哪知道?
反正debug的时候发现了就是了
C++标准库内部用的东西你是无法预测的.

顺便说一下,在全局变量的构造函数中也不要调用cout之类,因为它们可能还没初始化.

#6


我debug时,只是发现到了cout那行就会死机,我也是改成您这样去解决的。不过我没看出是由于delete会造成死循环的问题,您能教教我您是怎么看出来的吗?

#7


而且我在一个函数的静态对象的析构函数里调用cout输出也会有问题,可能就是您说的另一个问题了

#8


new delete 本来就是很常用的操作。运算符重载,或者替换一些常用函数,应该尽量做的简单,最好不要引用库函数。你可以只记录行号,或者增加计数,在外面打印。如果你怕不出问题,那不如在这些函数中调用什么messagebox之类的,保证你跟踪都跟不完。

#9


vc debug 的时候总会抛出异常吧,然后可以看到调用栈么-_-

main函数结束以后也不要调用cout,因为cout可能已经析购了.

#10


KeepRun(VOID) :其实我程序的原意是重载new和delete,对内存分配用链表记录,这样可以检测内存泄漏。只是问问题时为了简单删除了大部分。
谢谢您。请教您下如果您要检测内存泄漏,会怎么做?谢谢!

#11


你可以考虑class中自定的new,delete
这样就不用操心这么多了.

#12


yjh1982(血精灵):我也这么做了,这样就是不能发现如
int * p = new int(5)
这样的内存泄露,因为它是基本类型,所以我才重写全局的new和delete的

#13


原因就是你重载了全局的new操作,这就出现问题了

cout << "file: " << file << " line: " << line << endl;

在上面的这行操作中当输出 line时 cout 又调用了 new操作(你重载后的),
这样就陷入了死循环

#14


对于你想发现内存泄露的问题,你可以这样解决:
之所以出现死循环,是由于在cout中调用了delete,
所以你可以仅在你重载的new和delete中实现引用计数,并进行
相应的一定判断,如看两个的引用记数是否相等等操作,
而不要调用cout库函数,
而可以另写一个仅用于输出的函数OutputCount()中调用cout,
当且仅当你的引用记数满足内存泄露的条件时,你才调用你
的OutputCount()函数打印输出结果,
我觉的也能实现跟踪的效果吧,
这样应该不会出问题。

#15


// ^_^ 果真是调用delete 陷入死循环

#16


想问一下血精灵是怎么debug出来的,长见识了!

cout->delete->cout...

#17


按F5 debug调试,出异常时会停在某个位置.
就可以看到函数调用栈了

#18


我想问一下,void * 是代表什么?

#19


一个空指针,指向什么都可以,不过要赋值的时候要强制转换。

#20


纠正以下哈
void*            空类型指针
char* p = NULL;  空指针

#21


谢谢大家了

#22


听君一席话、胜读十年书!
谢谢大家!