也谈在动态连接库中如何使用STL库
2005-04-28 11:30
375 查看
(本文首发于CSDN,现转贴入博客园,稍有修改)
在动态连接库开发中要特别注意内存的分配与释放问题,稍不注意,极可能造成内存泄漏,从而访问出错。例如在某DLL中存在这样一段代码:
extent "C" __declspec(dllexport)
void ExtractFileName( const std::string& path //!< Input path and filename.
, std::string& fname //!< Extracted filename with extension.
)
{
std::string::size_type startPos = path.find_last_of('\\');
fname.assign(path.begin()+startPos+1, path.end() );
}
在DLL中使用STL对象std::string,并且在其中改变std::string的内容,即发生了内存的重分配问题,若在EXE中调用该函数会出现内存访问问题。主要是:因为DLL和EXE的内存分配方式不同,DLL中的分配的内存不能在EXE中正确释放掉。
解决这一问题的途径如下:
一般情况下:构建DLL必须遵循谁分配就由谁释放的原则,例如COM的解决方案(利用引用计数),对象的创建(QueryInterface)与释放均在COM组件内部完成。在纯C++环境下,可以很容易的实现类似方案。
在应用STL的情况下,很难使用上述方案来解决,因此必须另辟蹊径,途径有二:
1、自己写内存分配器替代STL中的默认分配器。
2、使用STLport替代系统的标准库。
其实,上述问题在VC7及以后版本中,已得到解决,注意DLL工程和调用的工程一定要使用多线程DLL库,就不会发生内存访问问题。
前两天看到蒋晟.Net 文章Visual C++ 2005的版本区别,其中谈到Visual C++ 2005不再支持单线程的CRT(LIBC.lib),看来以后这一问题要永远走进坟墓了!
在动态连接库开发中要特别注意内存的分配与释放问题,稍不注意,极可能造成内存泄漏,从而访问出错。例如在某DLL中存在这样一段代码:
extent "C" __declspec(dllexport)
void ExtractFileName( const std::string& path //!< Input path and filename.
, std::string& fname //!< Extracted filename with extension.
)
{
std::string::size_type startPos = path.find_last_of('\\');
fname.assign(path.begin()+startPos+1, path.end() );
}
在DLL中使用STL对象std::string,并且在其中改变std::string的内容,即发生了内存的重分配问题,若在EXE中调用该函数会出现内存访问问题。主要是:因为DLL和EXE的内存分配方式不同,DLL中的分配的内存不能在EXE中正确释放掉。
解决这一问题的途径如下:
一般情况下:构建DLL必须遵循谁分配就由谁释放的原则,例如COM的解决方案(利用引用计数),对象的创建(QueryInterface)与释放均在COM组件内部完成。在纯C++环境下,可以很容易的实现类似方案。
在应用STL的情况下,很难使用上述方案来解决,因此必须另辟蹊径,途径有二:
1、自己写内存分配器替代STL中的默认分配器。
2、使用STLport替代系统的标准库。
其实,上述问题在VC7及以后版本中,已得到解决,注意DLL工程和调用的工程一定要使用多线程DLL库,就不会发生内存访问问题。
前两天看到蒋晟.Net 文章Visual C++ 2005的版本区别,其中谈到Visual C++ 2005不再支持单线程的CRT(LIBC.lib),看来以后这一问题要永远走进坟墓了!
相关文章推荐
- 也谈在动态连接库中如何使用STL库
- 如何使用Nhibernate动态连接Oracle数据库
- FineReport如何连接和使用MongoDB数据库
- 简单实现如何使用 Socket 类实现面向连接的通信。
- 如何创建和使用动态链接(dll)和静态链接(lib),全面总结
- 如何实现SDI程序使用CSplitterWnd创建的多个视图的动态地显示和关闭视图
- 如何使用Amarino工具包连接Android手机和Arduino
- Docker如何使用link建立容器之间的连接
- 如何使用PHP DOM创建动态XML文件
- Oracle:如何使用PL-SQL 11.0连接远程Oracle12c服务器?
- 如何使用SecureCRT连接ubuntu
- 如何让matlab用mex与C连接使用有例子
- 如何使用三层框架开发 JDBC 连接 Mysql 数据库
- 64位sql server 如何使用链接服务器连接Access
- 远程桌面命令是什么 如何使用命令连接远程桌面
- 如何把手机摄像头连接到电脑使用
- Retrofit2-如何在请求时使用动态URL
- 如何使用后台代码在head标记中动态生成javascript?
- AD域用户如何使用内网环境exchange服务器连接和同步邮箱、日历、联系人和任务
- 在Java中如何使用jdbc连接Sql2008数据库