Home  >  Q&A  >  body text

c++ - 为什么析构函数什么也不写仍然会delete其成员指针?


class A{
public:
    int _a;
    A(int a) :_a(a){};
};
class B{
    A* _ap;
public:
    B(A& a){
        _ap = &a;
    }
    ~B(){
        //这里并不执行什么,但是_ap仍然被delete了。
    };
};
void main(){
    A* a = new A(1);
    B b(*a);
    delete &b;
    cout << a->_a;
}

是不是不管你析构函数写的什么,都一定会delete掉其所有的成员变量?

PHP中文网PHP中文网2765 days ago630

reply all(4)I'll reply

  • 怪我咯

    怪我咯2017-04-17 13:32:21

    Is it true that no matter what you write in the destructor, all its member variables will be deleted?

    Absolutely impossible.

    In addition, b is not new. The result of removing it delete is undefined.

    The above two can be said to be fatal errors! ! !
    Because the former will cause memory leaks
    the latter will cause your program to behave in a magical way at a magic moment method of crashing, and after crashing, it is basically difficult for you to discover the secret hidden in it.

    reply
    0
  • 迷茫

    迷茫2017-04-17 13:32:21

    There are several problems in the subject’s program:

    class A{
    public:
        int _a;  // 不推荐,变量名不要以下划线开始,但可以以下划线结束,比如 a_
        A(int a) :_a(a){};
    };
    class B{
        A* _ap;  // 同上
    public:
        B(A& a){
            _ap = &a;
        }
        ~B(){
            //这里并不执行什么,_ap 也没有在这里被 delete
        };
    };
    void main(){
        A* a = new A(1);
        B b(*a);
        delete &b;  // 错误,&b 并不是指向动态分配的内存的指针,对其进行 delete 是未定义的(见文末标准引用)
        cout << a->_a;
        delete a;  // 错误,a 是指向动态分配的内存的指针,需要进行 delete,而题主漏掉了
    }

    Is it true that no matter what you write in the destructor, all its member variables will be deleted?

    No. If you don't write delete, the destructor will not release the memory pointed to by the corresponding pointer.

    In addition, the title class B also has design problems. If a class member is a pointer, then you need to consider:

    • Does the member

      of B_ap point to an object on the stack or an object in dynamic memory?

      • If it points to an object on the stack, there is no need to consider memory allocation and release issues;

      • If it points to an object in dynamic memory, you need to consider memory allocation and release issues.

    • If it points to dynamic memory, who should manage (allocate, release) the pointed memory? Is it class B or a user of class B (such as a main function)?

      • If it is managed by class B (which is also the usual practice), then the corresponding constructor and destructor will be responsible for the allocation and release of dynamic memory. This is what is often called Resource Acquisition Is Initialization (RAII) in C++.

      • If
      • is managed by users of class B (such as main function), then users (such as main function) must carefully consider resource allocation and release issues during implementation, otherwise it will be very difficult Error prone.

    Finally, if you don’t have special needs, it is not recommended to use raw pointers. Instead, use smart pointers shared_ptr, weak_ptr and unique_ptr in STL. Smart pointers can automatically manage the dynamics they point to. Memory, so there is no need to consider when to release the memory, whether the same memory will be released multiple times, whether a wild pointer will be accidentally created, etc. For usage, please refer to C++ Primer 5e Chapter 12 Dynamic Memory.

    C++ 11 Standard § 5.3.5/2
    … In the first alternative (delete object), the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). If not, the behavior is undefined. …

    reply
    0
  • PHP中文网

    PHP中文网2017-04-17 13:32:21

    Only dynamic memory needs to be released manually, and the rest of the variables are automatically released when the class variable is destroyed. You don’t have dynamic memory allocation here, so you don’t need to write anything

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-17 13:32:21

    Two things:
    1. If the member variable is a pointer. Then the memory that the program needs to allocate is the memory occupied by the storage pointer (4 bytes for 32-bit programs) and the memory pointed to by the pointer. The memory occupied by the pointer is managed by the compiler, and the memory pointed to by the pointer is managed by you.
    That is, the memory occupied by this pointer (4 bytes) will be automatically released in the destructor. However, the default destructor of the part of the memory pointed to by the pointer will not help you release it, because the compiler does not know whether your pointer points to memory allocated by yourself, nor does it know whether you will use this memory in the future. .
    2. When the program/process is executed, all the memory occupied by the program will be released by the operating system. Even if there is no delete shown.

    reply
    0
  • Cancelreply