debug : 如果结构中有非内建类型数据,不能用ZeroMemory来清零结构体内存

来源:互联网 发布:php argv 参数 编辑:程序博客网 时间:2024/06/05 10:10

今天用VLD扫工程中的内存泄漏,发现了 ZeroMemory  结构体引起的内存泄漏.

// test0327.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <Windows.h>#include <string>#include <tchar.h>typedef struct _tagInfo{    int iAge;    std::wstring strNote;    _tagInfo()    {        iAge = 0;        strNote = L"";    }}INFO;int _tmain(int argc, _TCHAR* argv[]){    INFO Info;    /// 如果结构中有非内建类型数据,不能用ZeroMemory来清零结构体内存    // ::ZeroMemory(&Info, sizeof(Info)); ///< can't do this, memory leak here    Info.iAge = 18;    Info.strNote = L"a coder here";return 0;}

当清纯struct时,由于有血的教训,不推荐使用 ZeroMemory, 而要struct内自定义的clear()方法.


在使用数据结构和使用DTO之间,到底该用谁 ?

stackoverflow上的一个帖子说<<clean code>>第六章有讲.

看完<<clean code>>第六章,感觉作者的意思是至少要用DTO,  更好的做法是使用带seter,geter的数据类.


如果下次再遇到此类情况,我会使用带seter和geter的数据类.

这样,就不会发生struct内存泄漏的杯具.


杯具的发生如下:

* 工程一眼望不到头.

* 某天加了一个纯struct, 里面只有内建类型. 作者在需要struct归零时, 使用了 ZeroMemory. 这个struct归零的方法离struct定义的地方很远.

* 过了一段时间, 维护者(包括原作者)在struct中添加了一个非内建类型数据(e.g. 另外一个数据类 或者是 std::wstring这样的第三方的类).

这时,有可能(是有很大可能)想不起, 去想想ZeroMemory操作struct到底对不对, 好, 内存泄漏产生了.


总结:

  * 如果至少使用DTO, 绝对不会使用ZeroMemory来使DTO归零, 我们一定用DTO中的自定义的clear()方法. 我们也就从源头上防止了使用struct引起的内存泄漏。

  * 在结构中,绝对禁止使用非内建类型的成员变量.

  * 只有跨进程传递参数或socket通讯时,才考虑使用struct. 那时,类是不能跨进程或用于容纳socket通讯的内容.




















0 0
原创粉丝点击