首页 > 代码库 > 2017/03/11学习笔记

2017/03/11学习笔记

.lib资源模式文件 描述 .dll
.dll 动态库(函数二进制码集合,里面有函数的函数体),动态库有规范(win/linux)下不一样.

mtrace

是linux C编程内存泄漏检测工具,mtrace是三款工具中最简单易用的,mtrace是一个C函数,在<mckeck.h>里面声明及定义.
其实mtrace是类似malloc_hook的malloc handler,只不过mtrace的hander function已由系统为你写好,既然如此,系统又怎么知道您想将malloc/free的记录写在哪里?为此,调用mtrace前要设置MALLOC_TRACE环境变量.

setenv("MALLOC_TRACE","output_file_name",1);

output_file_name就是存储检测结果的文件名称。

但是检测结果的格式一般人无法理解,而只要安装mtrace的话,就会有一名为mtrace的Perl script,在sheel下输入:
mtrace [binary] output_file_name

Memwatch

Mem设置最简单.他能检测未释放的内存、同一段内存被多次释放、位地址存取错误及不当使用为分配的内存。
MemWatch将所有的分配内存用0xFE填充,所以,如果你看到错误的数据是0xFE,那就是你没有初始化数据。
MemWatch将所有已释放的内存用0xFD填充,如果你发现你使用的数据是0xFD,那就是使用已释放的内存。在这种情况下,MemWatch会立即把一个释放了的块信息填在释放了的数据前。这个块包括关于内存在哪儿释放的信息,以可读文本形式存放。

Win32下动态链接库(DLL)编程原理

比较大的应用程序都有很多模块组成,这些模块分别完成相对独立的功能,他们彼此协作来完成整个软件系统的工作。其中可能存在一些模块的功能比较通用,在构造其他软件系统时仍会被使用,在构造软件系统时,如果将所有的模块的源代码都静态额编译到整个程序中,会产生一些问题:一个是增加了程序的大小,要占用更多的磁盘空间,程序运行的时候也会消耗较大的内存。另一个问题是,在编写大的程序是,每次修改重建都必须编译所有源代码,增加编译的复杂性,也不利于阶段性的单元测试。

动态库内存释放问题

1.保证内存分配和释放的统一性:如果一个DLL提供一个能够分配内存的函数,那么这个DLL同事应该提供一个函数释放这些内存。数据的创建和释放应该在同一个层次上。
曾经遇到这样的例子:在dll中分配了内存,通过PostMEssage将其地址传给应用。然后去释放他,总是报异常。
2.如果EXE用MFC Appwizard方式生成,dll用wind32方式生成,则运行时会查询错误。进一步用单步跟踪,发现mfc方式和win32下的new操作符是用不同方式实现的,源程序分别在VC目录文件Afmem.cpp和new.cpp中。
因为DLL输出函数后,并不知道是哪一模块调用他,因此new和delete配对是最好在一个文件中。
3.问题主要在于DLL和EXE主程序分配内存的堆不一样,你可以不用 new和delete,而是使用
1)::HeapAlloc(::GetProcessHeap(),...)和::HeapFree(::GetProcessHeap(),...)
2)::GlobalAlloc()和GlobalFree()
这两点API,这样无论在DLL中还是主程序中都是在进程默认堆中分配,就不会出错了(JNI容易出错SSH项目中出错,不稳定)。
4.还有一个办法,就是把DLL的Settings的c/c++选项卡的Code Generation的Use Run-time liberary改成Debug Multitheaded DLL,在Release版本改成Multithread DLL,就可以直接使用new 和delete了。不过MFC就不能使用Shared模式了。

2017/03/11学习笔记