[C/C++]_[中级]_[使用智能指针的方式释放malloc出来的堆空间]

场景:

1. 使用auto_ptr 的方式可以wrap类对象,  之后在方法结束后可以自动释放对象, 参考;这样在有条件判断的语句时可以省掉free语句或CloseHandle.

http://blog.csdn.net/infoworld/article/details/9008911

2.C++的特性之一就是类对象(非返回值的对象)在方法结束后会自动调用析构函数,这样在析构函数里可以放一些释放资源的操作.

3. 这里实现了一个类似auto_ptr的类的实用Wrap类,可以参考根据自己需要自定义特定的Wrap类.auto_ptr的坏处之一就是只支持new出来的对象,

之二是不能删除数组. delete []

4. 恰当使用WrapObject能有效的减少内存泄漏,因为在很多C编程里, 太多的if语句在return前需要释放对象,很容易就会出错或多次释放。

文件 wrap_object.h

#ifndef __WRAP_OBJECT
#define __WRAP_OBJECT

#include <stdlib.h>
#include <Windows.h>

template<BOOL (WINAPI* WrapHandleFunc)(void*)>
class WrapHandle
{
public:
	WrapHandle(void* data):data_(data){}
	~WrapHandle()
	{
		if(data_)
		{
			WrapHandleFunc(data_);
			data_ = NULL;
		}
	}
private:
	void* data_;
};

class WrapMalloc
{
public:
	WrapMalloc(void* data):data_(data){}

	~WrapMalloc()
	{
		free(data_);
		data_ = NULL;
	}
	void Reset()
	{
		free(data_);
		data_ = NULL;
	}
private:
	void* data_;
};

#endif

使用方式:

// Specify an HTTP server.
  const char* www = "www";
  std::string URLADDR = DhOptionDomain::GetValue("url:brand");
  const char* www_start = strstr(URLADDR.c_str(),www);

  if( !hSession )
  {
	  return kNetworkError;
  }
  WrapHandle<WinHttpCloseHandle> session_wh(hSession);

  wchar_t* www_start_unicode = ConvertUtf8ToUnicode(www_start);
  WrapMalloc www_wm(www_start_unicode);
  hConnect = WinHttpConnect( hSession, www_start_unicode,
                               INTERNET_DEFAULT_HTTP_PORT, 0 ); 

  // Create an HTTP request handle.
  if(!hConnect )
  {
	 return kNetworkError;
  }
  WrapHandle<WinHttpCloseHandle> connect_wh(hConnect);

  hRequest = WinHttpOpenRequest( hConnect, L"GET", L"/win-update.xml",
                                   NULL, WINHTTP_NO_REFERER,
                                   WINHTTP_DEFAULT_ACCEPT_TYPES,
                                   WINHTTP_FLAG_REFRESH );
  // Send a request.
  if(!hRequest)
  {
	 return kNetworkError;
  } 

  WrapHandle<WinHttpCloseHandle> request_wh(hRequest);

  bResults = WinHttpSendRequest( hRequest,
                                   WINHTTP_NO_ADDITIONAL_HEADERS, 0,
                                   WINHTTP_NO_REQUEST_DATA, 0,
                                   0, 0 );

  // End the request.
  if(!bResults )
  {
	return kNetworkError;
  }
  bResults = WinHttpReceiveResponse( hRequest, NULL );  

注意: 如果没有WrapObject的话你就得记得在if里释放不断增加的 Handle对象,它是提高程序质量的好处之一,建议直接用到项目里.

时间: 2024-08-27 13:24:11

[C/C++]_[中级]_[使用智能指针的方式释放malloc出来的堆空间]的相关文章

[C/C++]_[中级]_[数据地址对齐]

场景: 1. 有些频繁使用的指针变量地址不对齐的话运行效率和对齐后的运行效率差别很大,所以在创建堆空间时,有必要对内存地址对齐提高运行效率. 2. 有些音视频处理的代码或者说自定义的malloc基本都是地址对齐的. 3. 使用原子访问的互锁函数时,InterlockedExchangeAdd都需要地址对齐. 4. 主要还是宏APR_ALIGN, 这个说是Apache源码里,就借用一下吧. 解决方案: 1. 其实就是让地址值对对齐量求模为0, 地址值最多增加n-1个偏移地址就可就可以整出n.  &

[C/C++]_[中级]_[delete 类对象指针的注意事项]

场景:1. C++类有构造和析构函数,析构函数是在类对象被delete时(或局部变量自动销毁时)调用来释放资源. 2. C++类对象指针很多情况下需要赋值给void*通用指针来达到传输对象的目的,但是往往这种void*指针就是造成内存泄漏或程序错误的根源, 这就是为什么C++存在泛型的目的,它也是为了在编译时刻消除这种对象不确定性,避免delete或使用时的错误. 好了,看代码,以下代码有什么问题? // test_class.cpp : 定义控制台应用程序的入口点. // #include "

[ATL/WTL]_[中级]_[使用GDIPlus剪切和缩放图片]

场景: 1. 缩放图片,不用多说,就是需要缩略图和画在界面上这类. 2. 剪切,不用多说,就是剪切一部分图片用于绘制控件背景之类. 3. wxWidget的wxImage都是自带这些功能的直接方法的. Gdiplus::Bitmap* CutImage(Gdiplus::Image* source,int x,int y,int width,int height) { Gdiplus::Rect zoomRect(0, 0, width,height); Gdiplus::Bitmap* pIm

[Windows]_[中级]_[界面程序打开控制台输出-转发输出到控制台]

场景: 1. 开发Windows界面程序时,需要打印输出,断点在调试多线程程序有局限性,就是会干扰线程的优先顺序,看不到正确的结果,往往就是断点就没事, 没断点程序就不能正常运行了. 2. 使用动态库(静态库)时,出现问题时在Dll里写std::cout输出信息是必不可少的调试方法,特别对于多线程程序,谁先谁后暂停后的结果就会不一样了. 有时候没有动态库的代码时,也没法对动态库打断点. 3.  打开控制台窗口后只能看到WIndows程序的输出而无法看到Dll的输出? 4. 直接改配置属性->链接

[ATL/WTL]_[中级]_[保存CBitmap到文件-保存屏幕内容到文件]

场景: 1. 在做图片处理时,比方放大后或加特效后须要保存CBitmap(HBITMAP)到文件. 2.截取屏幕内容到文件时. 3.不须要增加第3方库时. 说明: 这段代码部分来自网上.第一次学atl/wtl.gdi不是非常熟悉.以后转换为wtl版本号吧. 当然wtl项目直接用也没问题. 如今想想wxWidgets的wxImage类对这类操作方便多了.仅仅须要调用一个SaveFile方法. 保存HBITMAP到文件: static bool SaveBitmapToFile(CBitmap& b

[Windows]_[中级]_[使用命令行工具dumpbin分析文件]

dumpbin(vs自带) 1. 导出lib文件的函数符号(symbols) dumpbin /exports zlib1.lib Microsoft (R) COFF/PE Dumper Version 10.00.40219.01 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file zlib1.lib File Type: LIBRARY Exports ordinal name 1 [email pr

[ATL/WTL]_[中级]_[原生的复选框(checkbox button)和单选按钮(radio button)实现透明背景效果解决方案]

场景: 1. mfc,wtl的原生控件都是通过父窗口拦截 WM_CTLCOLORSTATIC 事件来修改子控件的颜色和背景色,CStatic可以通过返回HOLLOW_BRUSH来绘制透明背景: m_HollowBrush = AtlGetStockBrush(HOLLOW_BRUSH); 但是如果使用manifest文件使用最新 外观样式的话,返回HOLLOW_BRUSH对checkbox和radio button没有任何效果,原背景还是存在.虽然通过自绘一个checkbox和radio but

(转)Delphi2009初体验 - 语言篇 - 智能指针(Smart Pointer)的实现

快速导航 一. 回顾历史二. 智能指针简介三. Delphi中的interface四. Delphi中智能指针的实现五. interface + 泛型 = 强类型的智能指针!六. 智能指针与集合七. 注意事项八. 总结 本随笔所有源代码打包下载 一.回顾历史 在c++中,对象可以创建在栈里,也可以创建在堆里.如: class CTestClass{public: CTestClass() { printf("Create"); } void DoPrint() {} ~CTestCla

细说智能指针

提到指针,我们就会想到指针的高效,当然,滥用指针也会为我们带来许多的潜在bug.提到指针,我们就会想到内存泄漏.比如,使用指针后忘记释放,久而久之,堆空间就会全部使用完,那么会带来很大的危害.再比如,两个指针指向同一片内存区域,我们对同一片区域进行了多次释放,同样会造成内存泄漏.为了方便大家的理解,我们先来模拟一下,使用指针却忘记释放带来的危害.首先,我们要定义一个类.这次,还是定义女朋友类吧(之前写过一篇<细说C++的友元>用的就是女朋友类,这次还用这个吧,方便说明问题,更何况我们这群马畜怎