FeedBack:
#
re: std::string一个极其隐晦得问题
2006-04-18 16:55 |
此是老问题了,即跨module(exe、dll)间申请/释放内存违例的问题,对发生在传递c++对象并使用时,不仅仅发生在std::string上
原因是由于程序中使用的内存管理多来源于crt提供的例程,而非直接使用操作系统的接口,这些例程都需要维护一些module全局数据(例如维护池、维护空闲块、或者标记已申请的块等等,不同的实现中有不同的作用),当他们被静态连编时,实际上这些“全局数据”就不“全局”了,不同的module各自为政,每份module都有自己的“全局数据”,自身的内存信息不为他人所知,module A的合法内存快自然不可能通得过module B的合法性验证
解决问题的方法有:
1、不要跨module传递c++对象,或者避免释放跨module申请的内存
2、将参与合作的module统统以multithreaded dll方式链入crt库,让他们的“全局”数据真正全局,注意,所有有交互的module都需要动态链入crt,
不推荐第二种方式
回复
更多评论
#
re: std::string一个极其隐晦得问题
#
re: std::string一个极其隐晦得问题
2006-04-18 21:39 |
最好是用标准的C类型却是是一种准则。
个人认为:作为输出参数可以通过指针避免,输入参数一般没有问题,上面那个string仅仅由于实现上造成的,其实还可以这样避免:
SetString(std::string str)
{
m_str = str.c_str();
}
回复
更多评论
#
re: std::string一个极其隐晦得问题
2006-04-20 11:52 |
SetString(std::string str) 虽然避免了问题,但对象的复制造成了效率下降。我喜欢
<REF>
2、将参与合作的module统统以multithreaded dll方式链入crt库,让他们的“全局”数据真正全局,注意,所有有交互的module都需要动态链入crt,
</REF>
而且为了避免这种内存问题,我还自己做了一个内存回收的实现,所有模块只分配内存就行了
回复
更多评论
#
re: std::string一个极其隐晦得问题
2006-04-20 19:53 |
那么,使用这样不是更好?
SetString( const std::string & str ){
m_str = str;
}
回复
更多评论
#
re: std::string一个极其隐晦得问题
2006-04-20 22:17 |
SetString( const std::string & str ){
m_str = str;
}
这样不可以,因为这样m_str引用str地址,假如导出类对象是成员变量m_expOBJ,
有这样一段代码:
str = "wlw";
m_expOBJ.SetString(str);
m_expOBJ的m_str引用str指针,作用域过去后str析构,此时由于指针被引用,没有delete内存,而m_expOBJ析构的时候,m_str对象内部指针没有被引用,删除时恰好发现指针不合法,引起问题。
m_str = str.c_str();可以避免引用。
回复
更多评论
#
re: std::string一个极其隐晦得问题
2006-07-26 15:51 |
有一个不成文但是却是重要的前提, STL对象尽量不要作为dll的接口传递.
不过你说的问题应该是不存在的, 因为
SetString(std::string str)
{
m_str = str; //这里++ref
}
所以结果str还是存在一个ref供外部调用的.
回复
更多评论
#
re: std::string一个极其隐晦得问题
2008-06-12 10:45 |
我这几天也遇到这个问题,此问对我有很多帮助,非常感谢,发现用STL对象的确有很多问题,最好改用const char * 如果需要然后在进行转换。
回复
更多评论
#
re: std::string一个极其隐晦得问题
2011-07-30 07:48 |
不是stl本身有问题,而是stl的微软实现有问题,如果都用stlport就可以解决问题,因为微软判断一个字符串是否没有分配内存不是拿指针是否为NULL来比较,而是把它和一个全局的“null”字符串来比较,这样由于跨module后,出现了两个“null”字符串,所以导致错误。微软的实现比较的垃圾