Double data deletion does not fall

I am trying to learn C ++ and am writing programs to study constructor overloading and overloading. I am surprised that the program below does not crash when using the Copy constructor, saying "Double Free", whereas when using Operator = overloading sequences it crashes sequentially.

#include <iostream>
using namespace std;

class XHandler
{
    public:
    XHandler()
    {
            data = new char[8];
            strcpy(data, "NoName");
    }
    XHandler (const char *str)
    {
            data = new char (strlen(str) + 1 );
            strcpy (data, str);
    }
    XHandler (const XHandler &xh)
    {
            data = xh.data;
    }
    XHandler& operator = (const XHandler &xh)
    {
            data = xh.data;
    }
    ~XHandler()
    {
            delete data;
    }
    void debug()
    {
            cout << data <<endl;
    }
    private:
    char *data;
};

int main()
{
    XHandler wm("hello"), wb("there");
    wm.debug();
    wb.debug();
    XHandler wc (wm);
    wc.debug();
    XHandler wd;
    wd = wc;
    wd.debug();
}

, , , "" . "wd" "wc", . , . , wc wm , .

    XHandler wd;
    wd = wc;
    wd.debug();

, - undefined. , .

+4
3

"Undefined " - undefined. , , . "Undefined ".

, , . , , . , . , , , .

BTW: , .

+5

, , , , , , Linux, Codeblock IDE

#include <iostream>
#include <cstring>
#include <stdio.h>
using namespace std;

class XHandler
{
    public:
    XHandler()
    {
            data = new char[8];
            strcpy(data, "NoName");
            std::cout<< "default construcor is called" << std::endl;
    }
    XHandler (const char *str)
    {
            data = new char [strlen(str) + 1 ];
            strcpy (data, str);
             std::cout<< "param construcor is called" << std::endl;

    }
    XHandler (const XHandler &xh)
    {
            data = xh.data;
            std::cout<< "copy construcor is called" << std::endl;

    }
    XHandler& operator = (const XHandler &xh)
    {
            data = xh.data;
            std::cout<< "operator construcor is called" << std::endl;

            return *this;
    }
    ~XHandler()
    {
        std::cout<< "destrucor is called" << std::endl;
        print_dir();
        if (data)
        {
            delete [] data;
            data = NULL;
            std::cout<< "delete data" << std::endl;
        }



    }
    void debug()
    {
            cout << data <<endl;
    }
    void print_dir()
    {
        printf("location: %p\n",data);
    }
    private:
    char *data;
};

int main()
{
    XHandler wm("hello"), wb("there");
    wm.debug();
    wb.debug();
    wm.print_dir();
    wb.print_dir();
    XHandler wc (wm);
    wc.print_dir();
    wc.debug();
    XHandler wd;
    wd = wc;
    wd.debug();
}

linux gcc4.1.2,

param construcor is called
param construcor is called
hello
there
location: 0x502010
location: 0x502030
copy construcor is called
location: 0x502010
hello
default construcor is called
operator construcor is called
hello
destrucor is called
location: 0x502010
delete data
destrucor is called
location: 0x502010
*** glibc detected *** ./test: double free or corruption (fasttop): 0x0000000000502010 ***
+2

undefined.

:

data = new char (strlen(str) + 1 );

strlen(str) + 1. strlen(str) + 1 . strcpy , ( strlen (str) -1 ). , :

data = new char [strlen(str) + 1 ];

-, delete[] data;. undefined.

-, strcpy- NULL- . :

data[ strlen(str) ] = 0;

strcpy; (. ).

, , . - UB.

0
source

Source: https://habr.com/ru/post/1527465/


All Articles