Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在析构函数中将类成员设置为null_C++_Destructor - Fatal编程技术网

C++ 在析构函数中将类成员设置为null

C++ 在析构函数中将类成员设置为null,c++,destructor,C++,Destructor,在第页中有一段代码: class MyString { private: char *m_pchString; int m_nLength; public: MyString(const char *pchString="") { // Find the length of the string // Plus one character for a terminator m_nLength = strle

在第页中有一段代码:

class MyString
{
    private:
    char *m_pchString;
    int m_nLength;

public:
    MyString(const char *pchString="")
    {
        // Find the length of the string
        // Plus one character for a terminator
        m_nLength = strlen(pchString) + 1;

        // Allocate a buffer equal to this length
        m_pchString = new char[m_nLength];

        // Copy the parameter into our internal buffer
        strncpy(m_pchString, pchString, m_nLength);

        // Make sure the string is terminated
        m_pchString[m_nLength-1] = '\0';
    }

    ~MyString() // destructor
    {
        // We need to deallocate our buffer
        delete[] m_pchString;

        // Set m_pchString to null just in case
        m_pchString = 0;
    }

    char* GetString() { return m_pchString; }
    int GetLength() { return m_nLength; }
};

在析构函数中,编写器将mu pchString设置为null,并表示以防万一。如果不将其设置为null,会发生什么?我们已经释放了指定的内存,类成员将在退出时被杀死。这样做的好处是什么?

如果不将其设置为NULL,则没有什么坏处。删除对象后,无论如何都不应该访问其成员数据。

如果指针设置为
NULL
,则使用已删除对象的错误(例如通过指向该对象的悬空指针)实际上可能会被隐藏,因为错误代码可能会在尝试使用数据之前检查
NULL
。在一种思维方式中,可能会考虑“安全”的行为,但发生的是,你实际上隐藏了已经发生的缺陷。 请记住,隐藏bug与修复bug是不同的。在重新分配内存后,该悬空指针可能会再次使用,并将有效指针放在同一内存位置。此时,错误代码将开始使用新的有效指针,但原因不正确

因此,实际上最好将指针设置为如果使用不当会导致崩溃的对象:

m_pchString = (char*) 0xdeaddead;
现在,如果某个东西试图使用已删除对象(这是一个bug)的成员指针,它将很快失败,bug将被捕获而不是隐藏


在使用MSVC(可能还有其他工具链)的调试构建中,您已经在调试堆中获得了这种行为。MSVC调试堆将通过
free()
运算符delete
释放的内存填充为0xdd:

当您已经删除了内存位置时,析构函数只是一种很好的编程实践,它只会在出现任何隐藏错误时提供帮助。

在Michael Burr提供的答案旁边,在Tietbohl提供的链接的帮助下,也可以是一个很好的答案。我引述:

它可以帮助捕获对空闲内存的许多引用(假设您的平台在一个空指针上出现错误)

例如,如果您有指针的副本,它将不会捕获对空闲内存的所有引用。但有总比没有好

它会屏蔽双重删除,但我发现这种情况远不如访问已经释放的内存常见

在许多情况下,编译器会对其进行优化。所以说这是不必要的论点说服不了我

如果您已经在使用RAII,那么代码中的删除就不多了,因此额外的赋值会导致混乱的说法无法说服我

调试时,通常可以方便地看到空值,而不是过时的指针

如果这仍然困扰您,请使用智能指针或引用


这段代码实际上没有效果,优化编译器可以完全删除它。