65.9K
CodeProject 正在变化。 阅读更多。
Home

C++ 中的跟踪实用程序

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.29/5 (7投票s)

2003年2月4日

1分钟阅读

viewsIcon

73198

downloadIcon

720

本文介绍了队列的插入和删除

引言

对于复杂且大型的应用,编写我们自己的跟踪实用程序非常重要。 这很有用,因为 C++ 没有像 C# 或 Java 那样的垃圾回收 (GC) 概念,后者会自动处理这些问题。 如果您正在尝试查找错误或在应用程序生产过程中经常出现的难以找到的内存泄漏,一个好的跟踪文件可以提供很大的帮助。

因此,我们需要一个易于使用的实用程序,可以在应用程序运行时检测内存泄漏。 它还能查明内存泄漏的确切位置以及未释放的内存量。

Using the Code

主要是,我们希望重写 new 函数,以便每次调用 new 时,它都会添加跟踪信息,当然对于 delete,我们必须删除跟踪信息。 这两种方法应该彼此同步。 未调用 delete 将会触发内存泄漏。

#define DEBUG_NEW new(__FILE__, __LINE__)

  inline void * __cdecl operator new(size_t size,
        const char *fileName, int lineNumber)
  {
    void *ptr = (void *)malloc(size);
    addTrace((DWORD)ptr, size, fileName, lineNumber);
    return(ptr);
  };

对于 delete,应该这样调用

void __cdecl operator delete(void *p)
{
  removeTrace((DWORD)p);
  free(p);
};

为了检查结果,我们需要一个辅助方法来遍历内存泄漏

void Dump()
{
  AllocatedList::iterator i;
  DWORD totalSize = 0;
  char buf[1024];

  if(!allocatedList)
    return;

  for(i=allocatedList->begin(); i!=allocatedList->end(); i++) 
  {
    sprintf(buf, 
      "%-50s:\t\tLINE %d,\t\tADDRESS %d\t%d NOTFREED\n",
      (*i)->fileName, 
      (*i)->lineNumber, 
      (*i)->address, 
      (*i)->size);
    printf("%s",buf);
    totalSize += (*i)->size;
  }

  sprintf(buf, "\n---------------------------------\n");
  printf("%s",buf);
  if(!totalSize) 
  {
    sprintf(buf,"There are no MEMORY LEAKS\n");
    printf("%s",buf);
  }
    else
  {
    sprintf(buf, 
      "Total UNFREED MEMORY: %d bytes\n", 
      totalSize);
    printf("%s",buf);
  }
};

我使用了一个 List 来迭代遍历元素。

main()
{
  char *str = "This is a Testing Program";
  int len = strlen(str);
  char *ptr;
  ptr = DEBUG_NEW char[len+1];
  strcpy(ptr,str);
  delete ptr;
  Dump();
}

请查看 main 函数:我不是调用 new char[len+1];,而是调用 DEBUG_NEW。 这将添加跟踪信息,而 delete 将删除跟踪信息。

我仍然不知道是否有办法直接调用 DEBUG_NEW 而不是 new

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.