mardi 3 août 2021

C++11, using printf("%p", *this) in member function will call destructor, why?

#include <iostream>
#include <string>

#include "stdlib.h"
#include "stdio.h"

class Test
{
public:
    int *arr;
    virtual void f1(){};
    void f2(){};

    Test()
    {
        arr = new int[5];
    }

    ~Test()
    {
        delete[] arr;
        arr = nullptr;
        std::cout << " call ~Test()" << std::endl;
    }

    void show()
    {
        printf("start show\n");

        printf("*this address:%p\n", *this);//【1】

        printf("exit show\n");
    }
};

int main()
{
    Test *c = new Test();
    c->show();

    //c->~Test();//【2】
    c->arr[1] = 5;//【3】

    while (1);
    std::cout << "return 0;" << std::endl;
    return 0;
}

/*
Compiler version: gcc version 7.5.0 (Ubuntu 7.5.0-3 Ubuntu 1 ~ 18.04)
Compile and run under ubuntu18:
$ g++ destractor.cpp -o destractor -std=c++11
$./destractor 
start show
*this address:0x7fffbe1cb2f0
 call ~Test()
exit show
*/

Please pay attention to the code at position [1], as long as it is used, the destructor will be called.

Assuming that the destructor is really called, it is reasonable to say that when code at position [3] is executed, there will be a segment error, because arr has been released, but there is no segment error here. If the annotation at position [2] is removed, the program will execute to position [3], and a segment error will occur. Then the question is coming: Q1: Why does the code at position [1] call the destructor? Q2: It seems that calling destructor at [1] is different from that at [2]. Although destructor is called at [1], there will be no segment error, but it will lead to segment error at [2]. Although destructor is called at position [1], why can't arr's memory be released?

Thank you!

Aucun commentaire:

Enregistrer un commentaire