Arvin

C++博客 首页 新随笔 联系 聚合 管理
  1 Posts :: 0 Stories :: 0 Comments :: 0 Trackbacks
fdcf2003@yahoo.com.cn谢谢!
此是老问题了,即跨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,

不推荐第二种方式
用c/c++还是得看看iso/iec 9899和14882啊,msdn确实系统且有条理,但其中ms扩展的太多,使人未免难辨其里

例如关于errno,标准就有明确的说法,9899:1999, 7.5节
re: 目前要开发的东西 cf 2006-04-13 13:49
万一用户系统突然崩溃,好不容易安装的后门岂不是自动清除了?呵呵
寒~~~~出来两贴,请楼主删除一帖,和本贴,谢
提几点看法:

1、阁下这种thunk和atl中“使用Thunk将即将传递给窗口过程的第一个参数(HWND hWnd)的值使用类对象的内存地址(即this指针)进行替换”的thunk,形式上不同,本质上都是一样的,无非就是为member function找一个this而已,只不过前者直接由thunk->member,而后者为thunk->static->member,多一个call多费几十个机器周期而已,呵呵,在oop的dispatcher模型中,不知道要多多少层无谓的call呢

2、thunk技术本质上就是为不同的window指定不同的wndproc(地址)由此建立window->object的映射,mfc中用了hwnd->ptr的map,atl用了thunk,map的方式慢,但通用性强,thunk的方式快,但有硬伤,就是在不同的目标硬件上thunk多半是不同的,采用定制的方式局限性太强,例如:我们可以看到atl的src里面有宏可以为x86目标和alpha目标定制了不同的thunk,那么如果再需要增加x64和ia64构架还需要再增加,那么未知的目标(不过window平台似乎也没什么未知的目标了,呵呵)该如何呢?

n年没有研究windows gui了,上述观点定有疏失,还望指正
提几点看法:

1、阁下这种thunk和atl中“使用Thunk将即将传递给窗口过程的第一个参数(HWND hWnd)的值使用类对象的内存地址(即this指针)进行替换”的thunk,形式上不同,本质上都是一样的,无非就是为member function找一个this而已,只不过前者直接由thunk->member,而后者为thunk->static->member,多一个call多费几十个机器周期而已,呵呵,在oop的dispatcher模型中,不知道要多多少层无谓的call呢

2、thunk技术本质上就是为不同的window指定不同的wndproc(地址)由此建立window->object的映射,mfc中用了hwnd->ptr的map,atl用了thunk,map的方式慢,但通用性强,thunk的方式快,但有硬伤,就是在不同的目标硬件上thunk多半是不同的,采用定制的方式局限性太强,例如:我们可以看到atl的src里面有宏可以为x86目标和alpha目标定制了不同的thunk,那么如果再需要增加x64和ia64构架还需要再增加,那么未知的目标(不过window平台似乎也没什么未知的目标了,呵呵)该如何呢?

n年没有研究windows gui了,上述观点定有疏失,还望指正
在m$ weak vc2003中可以这样变通:
template < typename Ty >
struct dummy
{
template < Ty a >
struct damn
{
};
};

TmTm < int, dummy < int >::damn > obj;
05没试,大抵也可通过
第二种static的写法的确是愚见,呵呵

这么一来用户岂不是只能travel一遍了,第二遍的第一个期望的cnt已经不是0了(node数不为0)
about b
这个应该是库实现的不同,而非编译器的吧,呵呵

c++标准规定template class basic_string的iterator是
typedef implementation defined iterator;
这样的,即使vc6附带的pj库有
typedef char* iterator;
这样的定义,也不能认为二者有必要联系吧,换句话说,即便在vc6(with那个pj库)中
char *p = s.begin();
能被编译通过,这么些也是不妥当的,呵呵
re: C++和java的效率 cf 2006-03-08 15:22
呵呵,我倒不认为这样好,加一个jit显得有些不伦不类了,且和c/c++的静态格格不入,而且实际上c/c++并没有限制用户定义变通的“jit”:编译多份同功能的代码,产生多个不同平台的目标(不是x86和arm这么截然不同的平台,而是586和686这个层面的不同平台),根据不同平台进行优化,然后用一个载入器根据运行平台载入相应的较优版本,就好像游戏在安装时选择显卡一样。虽然和jit的方式有本质不同但原则上效果是类似的

实际上“新指令”带来的好处只在运算密集之处能体现出来,另一方面这种应用并不会常常出现,也就是说这个jit并非共性需求,而是个性需求,c/c++崇尚的就是不拘一格的实现方式嘛,呵呵
re: C++和java的效率 cf 2006-03-08 14:55
呵呵,我说呢,我记得有相关参数的,又去查了一下

http://gcc.gnu.org/onlinedocs/gcc-3.4.5/gcc/i386-and-x86_002d64-Options.html
re: vector::capacity cf 2006-03-06 14:09
楼主你总结的“不同”是库实现的不同,而不是编译器的不同