C++ 一不小心被delete两次

[来源] 达内    [编辑] 达内   [时间]2012-09-11

C++类中,有时候使用到传值调用(对象实体做参数),遇到这种情况,可要小心了!特别是当你所传值的对象生命周期较长,而非临时对象(生命周期段)的时候

C++类中,有时候使用到传值调用(对象实体做参数),遇到这种情况,可要小心了!特别是当你所传值的对象生命周期较长,而非临时对象(生命周期段)的时候。来看看下面的情况:

< div style="margin: 0px; padding: 0px; color: rgb(17, 17, 17); font-family: verdana, arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 23px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); "> < div style="margin: 1em 0px !important; padding: 1px !important; width: 919px; position: relative !important; overflow-x: auto !important; overflow-y: hidden !important; font-size: 15px !important; background-color: white !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; line-height: 1.5 !important; " class="syntaxhighlighter cpp" id="highlighter_253164"> < div style="margin: 0px !important; padding: 0px !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-left-radius: 0px !important; background-color: rgb(108, 226, 108) !important; border: none !important ; bottom: auto !important; float: none !important; height: 11px !important; left: auto !important; line-height: 1.5 !important; outline: 0px !important; overflow: visible !important; position: absolute !important; right: 1px !important; text-align: left !important; top: 1px !important; vertical-alig n: baseline !important; width: 11px !important; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 10px !important; min-height: inherit !important; z-index: 10 !important; color: white !important; background-position: initial initial !important; background-repeat: initial initial !important; " class="toolbar"> ?
< table cellspacing="0" cellpadding="0" border="0" style="margin: 0px auto; padding: 0px !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-left-radius: 0px !important; background-image: none !important ; border: 1px solid rgb(192, 192, 192); bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.5 !important; outline: 0px !important; overflow: visible !important; position: static !important; right: auto !important; text-align: left !importan t; top: auto !important; vertical-align: baseline !important; width: 919px; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 15px !important; min-height: inherit !important; border-collapse: collapse; background-position: initial initial !important; background-repeat: initial initial !important; ">
1
#include <iostream>
< div style="margin: 0px; padding: 0px; color: rgb(17, 17, 17); font-family: verdana, arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 23px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); "> < div style="margin: 1em 0px !important; padding: 1px !important; width: 919px; position: relative !important; overflow-x: auto !important; overflow-y: hidden !important; font-size: 15px !important; background-color: white !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; line-height: 1.5 !important; " class="syntaxhighlighter cpp" id="highlighter_837911"> < div style="margin: 0px !important; padding: 0px !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-left-radius: 0px !important; background-color: rgb(108, 226, 108) !important; border: none !important ; bottom: auto !important; float: none !important; height: 11px !important; left: auto !important; line-height: 1.5 !important; outline: 0px !important; overflow: visible !important; position: absolute !important; right: 1px !important; text-align: left !important; top: 1px !important; vertical-alig n: baseline !important; width: 11px !important; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 10px !important; min-height: inherit !important; z-index: 10 !important; color: white !important; background-position: initial initial !important; background-repeat: initial initial !important; " class="toolbar"> ?
< table cellspacing="0" cellpadding="0" border="0" style="margin: 0px auto; padding: 0px !important; border-top-left-radius: 0px !important; border-top-right-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-left-radius: 0px !important; background-image: none !important ; border: 1px solid rgb(192, 192, 192); bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.5 !important; outline: 0px !important; overflow: visible !important; position: static !important; right: auto !important; text-align: left !importan t; top: auto !important; vertical-align: baseline !important; width: 919px; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-weight: normal !important; font-style: normal !important; font-size: 15px !important; min-height: inherit !important; border-collapse: collapse; background-position: initial initial !important; background-repeat: initial initial !important; ">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<iostream>< div   style= "display: inline-block; " >< div > using  namespace  std;
 
class  Text
{
private :
     char  * str;
 
public :
     Text(){str = new  char [20];:: memset (str,0,20);}
     void  SetText( char  * str)
     {
         strcpy ( this ->str,str);
     }
     char  * GetText() const { return  str;}
     ~Text()
     {
         cout << "~Text Destruction"  << endl;
         delete   str;
         cout << "~Text Over"  << endl;
     }
};
 
void  Print(Text str)
{
     cout << str.GetText() << endl;
}
 
int  main()
{
     Text t;
     t.SetText( "abc" );
     Print(t);
     return   1;
}</ div ></ div ><br></iostream>
< p style="margin: 5px auto; padding: 0px; text-indent: 0px; color: rgb(17, 17, 17); font-family: verdana, arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 23px; orphans: 2; text-align: -webkit-auto; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); ">上面执行的结果程序崩溃了。原因:

< blockquote style="margin: 10px 0px 10px 25px; padding: 5px 10px; background-image: none; background-color: rgb(255, 255, 255); border: 2px solid rgb(239, 239, 239); color: rgb(51, 51, 51); font-family: verdana, arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; le tter-spacing: normal; line-height: 23px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-position: initial initial; background-repeat: initial initial; ">

Print(Text str)在对str进行复制构造的时候,没有进行深度拷贝;当 Print退出的时候,因为是临时对象(函数初始时构造),对str进行析构,此时还没有任何破绽;但回到main,继而退出main 的时候,又对t进行析构,但此时t内的str中的内容已经被销毁。由于对一内存空间实施了两次销毁,于是出现内存出错。

< p style="margin: 5px auto; padding: 0px; text-indent: 0px; color: rgb(17, 17, 17); font-family: verdana, arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 23px; orphans: 2; text-align: -webkit-auto; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); ">解决方法:

< ol style="margin: 0px; padding: 0px 0px 0px 50px; color: rgb(17, 17, 17); font-family: verdana, arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 23px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); ">
  • 重写浅拷贝。像一下版本,不同的情况要作出适当的调整:
    #include <iostream>
    using namespace std;
    class Text
    {
    private:
    char * str;
    public:
    Text(){str = new char[20];::memset(str,0,20);}
    Text(Text &t)
    {
    str = new char[20];
    strcpy(str,t.GetText());
    }
    void SetText(char * str)
    {
    strcpy(this->str,str);
    }
    char * GetText() const{return str;}
    ~Text()
    {
    cout << "~Text Destruction" << endl;
    delete str;
    cout << "~Text Over" << endl;
    }
    };
    void Print(Text str)
    {
    cout << str.GetText() << endl;
    }
    int main()
    {
    Text t;
    t.SetText("abc");
    Print(t);
    return 1;
    }
  • < ol style="margin: 0px; padding: 0px 0px 0px 50px; color: rgb(17, 17, 17); font-family: verdana, arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 23px; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); ">
  • (推荐)不使用传值调用。就像下面书写如下Print版本:
    ?
    1
    <br>
  • 除非对象内所有的成员读属非指针内存内容,那么谨慎使用文章前面的用法。
  • < h2 style="margin: 0px; padding: 0px; font-weight: bold; color: rgb(0, 0, 0); font-family: verdana, arial; font-style: normal; font-variant: normal; letter-spacing: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); ">
    后记——语言的探讨 < p style="margin: 5px auto; padding: 0px; text-indent: 0px; color: rgb(17, 17, 17); font-family: verdana, arial; font-size: 13px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 23px; orphans: 2; text-align: -webkit-auto; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); "> C++,以至于其他的程序语言,都是伟大的创造。他们是规则的世界,一愣一脚皆规则。当对某一规则有所熟知之后 ,就似发现新大陆似的。但想想,这些规则可经不起碰撞打击,殃及的是coder,是我们。这些规则不像1+1=2,“三点定面”来的铁定,总之比起数学理论来说,似乎程序规则脆弱很多,总之在它们身上看到的价值是有限的,总我还是选择了计算机...为之奈何,不得而知。

    资源下载