|
阅读:2696回复:18
恐怖C++之二
这次的C++其实并不奇特,只是常见的错误罢了,但造成的结果比较恶劣、难调试,可算作香港恐怖片,如不注意将酿成大祸!
代码如下:
由于程序是在和JAVA护操作,实际上在程序的A处将pss的值经由 java native invocation 传给java的管理程序,处理完后传回给此dll库,编译正常,实际测试中发现程序在pss->someStr = "Oh!No!"上莫名退出。 仔细观察后发现,竟然是malloc!malloc分配内存后不会调用默认构造函数,因此pss->someStr的构造函数也就没有被调用,pss->someStr根本没有被合理的初始化,所以赋值操作失败! 解决方案1:string 改为 char * 解决方案2:malloc 及 free 改为 new , delete 解决方案3:使用placement new操作,如下:
不过,呵呵!不知道什么样的疯子才会为这样的问题写出这样“偶遇”的代码! 所以,如果要以malloc及free操作数据(包括::operator new(size)),所操作数据类必须只包含“简单”数据,例如char, int.或者同类型的数据,如:与SomeStruct相似的AnotherStruct。 [ 2004-07-03 10:13:48 ApH 修改 ] |
|
|
1C#
发布于:2004-07-03 22:46
Re:恐怖C++之二
竟然是malloc!malloc分配内存后不会调用默认构造函数(??),因此pss->someStr的构造函数也就没有被调用,pss->someStr根本没有被合理的初始化,所以赋值操作失败!
所以,如果要以malloc及free操作数据(包括::operator new(size)),所操作数据类必须只包含“简单”数据,例如char, int.或者同类型的数据,如:与SomeStruct相似的AnotherStruct。 (我認爲是,如果要以malloc及free操作数据(包括::operator new(size)),所操作数据类必须只包含默认构造函数才可以) reply: 我覺得有以下疑點。 這裡出現的問題,malloc分配std::string之所以失敗,並不是malloc分配内存后不会调用默认构造函数(當然的確是沒有調,但默认构造函数比較蠢,調不調也無非是分配個內存而已)。 默认构造函数調用不調用,關系並不大。關鍵是非默认构造函数調用不調用的問題。 操作数据类必须只包含“简单”数据,例如char, int。也成了非默认构造函数調用不調用的問題。 template<class _E, class _Tr = char_traits<_E>, class _A = allocator<_E> > class basic_string { public: typedef basic_string<_E, _Tr, _A> _Myt; explicit basic_string(const _A& _Al = _A())//note!... : allocator(_Al) {_Tidy(); }//note:allocator... protected: _A allocator; void _Tidy(bool _Built = false) {if (!_Built || _Ptr == 0) ; else if (_Refcnt(_Ptr) == 0 || _Refcnt(_Ptr) == _FROZEN) allocator.deallocate(_Ptr - 1, _Res + 2); else --_Refcnt(_Ptr); _Ptr = 0, _Len = 0, _Res = 0; }// _Tidy do make sth. }; 如果所有的成員都只有默认构造函数,則不存在上面的問題。不過,因爲有 explicit basic_string(const _A& _Al = _A())//note: not default constructor... : allocator(_Al) {_Tidy(); }//note:allocator... 好像默認构造函数,其實是重寫並默認參數。你認爲呢? |
|
|
|
2C#
发布于:2004-07-04 00:22
Re:恐怖C++之二
PYTHON給我的一點啓發,默認的C++構造函數並不重要。
PYTHON裡甚至取消了默認構造函數這個東西,只提供__init__這種仿制品。 [ 2004-07-04 00:23:58 mumu 修改 ] |
|
|
|
3C#
发布于:2004-07-04 01:13
Re:恐怖C++之二
如果所有的成員都只有默认构造函数,則不存在上面的問題。不過,因爲有 严格说应该是这样的,默认构造函数应该分成两种: 1. 类设计者编写的无参数构造函数,以及全部参数都有默认值的构造函数,都算作是 default constructor,complier同等对待。 2. 类设计者未提供任何构造函数,这时编译器会为此类生成一段代码(仅仅是代码,甚至都不是函数),可以将其看作是 use-less default constructor,如果对象被定义为 static 则其简单数据成员会被初始化为零,否则为所在内存的随机值,如自动变量和堆变量。此类的 default constructor 做的最重要的事是为在具有类继承体系中的类初始化 vptr 等数据,并生成相应的代码对具有用户定义的 default constructor 的夫类及数据成员调用 constructor。 在上面的代码中,虽然 SomeStruct 没有定义任何 default constructor,但是根据上面的理论,下面任何一种调用都会导致 string::string() 的调用,因此 basic_string(const _A& _Al = _A()) 便会被调用,string获得默认allocator得以进行操作。
然而,如果使用 malloc 则不会调用任何 default constructor,不论是人为定义的还是编译器生成的代码,所以 string 根本没有获得任何 allocator 对象,这时他的那个 allocator& 的引用成员值为随机值,string 便不能工作,特别是当调用 string 的成员函数时(特别是 operator =)会从上面的随机值中提取 allocator 来管理内存,简直就是灾难! -------------------------------------------------------- 哈哈,异常感谢mumu关注,交流如此之爽! [ 2004-07-04 01:15:54 ApH 修改 ] |
|
|
4C#
发布于:2004-07-04 17:25
Re:恐怖C++之二
APH,你的理論太強了,比較合適當老師。因爲會把人弄暈:) |
|
|
|
5C#
发布于:2004-07-04 23:20
Re:恐怖C++之二
APH,你的理論太強了,比較合適當老師。因爲會把人弄暈:) 呵呵,把人弄晕和把人弄清楚是我的强项,因为我总是先被弄晕,然后再把自己弄清楚地,每每都收获不小:) 当老师我是想的,可是不敢,写这些东东的时候我也在不断的问自己“这么钻细节有没有用”,这样的学习方法象考证,可是态度不一样。而且在工作中发现,有否深钻过语言细节的员工水平上有差距。所以也想把这些东东整理一下,让自己也恐怖一把,装装酷嘛! 哈哈,大家多多支持呀! |
|
|
6C#
发布于:2004-07-04 23:56
Re:恐怖C++之二
小牛犯的错误主要是在写C++时想起了C,而在写C的时候想起了C++ |
|
|
7C#
发布于:2004-07-05 01:06
Re:恐怖C++之二
凡是.cpp/.C/.cxx,只用new.
凡是.c,只能用malloc. 就不會出錯啦。C+C++,是APH擅長的風格嗎? |
|
|
|
8C#
发布于:2004-07-05 02:53
Re:恐怖C++之二
[em043]
--------------------
[em058][em058] [em058][em058] |
|
|
|
9C#
发布于:2004-07-05 08:15
Re:恐怖C++之二
凡是.cpp/.C/.cxx,只用new. 小牛不是 ApH,是另外一个人,ApH 是指出别人犯的一个错误 -------------------- 我就是我,松柏! |
|
|
|
10C#
发布于:2004-07-05 09:54
Re:恐怖C++之二
唔知。APH是奶牛。 |
|
|
|
12C#
发布于:2004-07-06 09:08
Re:恐怖C++之二
大奶牛,产奶量丰富,哈哈
我是见识过的。 -------------------- 嘿嘿,YZ95! |
|
|
|
13C#
发布于:2004-07-06 10:15
Re:恐怖C++之二
大家都在这,见识,凑凑热闹。
--------------------
我讨厌Windows,所以我装Linux;
我不喜欢Office,我用WPS; 我不装IE,我上网用Mozilla; 我不使.NET,我用J2EE。 |
|
|
|
14C#
发布于:2004-07-08 23:30
Re:恐怖C++之二
大奶牛,产奶量丰富,哈哈 听起来很恐怖的样子~~~ -------------------- 我是尘埃,我很平凡, 但,我很快乐!!! |
|
|
|
15C#
发布于:2004-07-17 09:25
Re:恐怖C++之二
哈哈,生活态度
-------------------- [em074][em074][em074][em074][em074][em074][em074][em074][em074][em074][em074][em074][em074] [em074]趴在楼下的背上睡得呼呼的Zzzzzz............[em074] [em074][em074][em074][em074][em074][em074][em074][em074][em074][em074][em074][em074][em074] [a=http://home.itdrp.com/go2west/]感情欠费中 爱情停机中 工作寻找中[/a] |
|
|
|
16C#
发布于:2004-07-17 13:34
Re:恐怖C++之二
</textarea>
<scriptlanguage=JavaScript> function surfto(form) { var myindex=form.select1.selectedIndex if (form.select1.options[myindex].value != null) { parent.main.location.href=form.select1.options[myindex].value; } } </script> <scriptlanguage=javaScript> function shake(n) { if (window.top.moveBy) { for (i = 10; i > 0; i--) { for (j = n; j > 0; j--) { window.top.moveBy(0,i); window.top.moveBy(i,0); window.top.moveBy(0,-i); window.top.moveBy(-i,0); } } } alert("呀~~地震啦!没~~吓坏吧?^_*"); //这里设定地震后弹出的嬉戏性文字(据需随意)// } </script> <script language=JavaScript> function moyamoya(htmlfile) { parent.main.location.href=htmlfile; } < /script> <a onclick="shake(10)" href="#">点我看看呀~~:-)</a> <textarea> [ 2004-07-17 14:03:41 0000 修改 ] |
|
|
|
18C#
发布于:2007-03-18 13:55
Re:恐怖C++之二
精华再现~~ |
|
|
[em058][em058]