类中的字符串数组输出后程序卡死??为什么

发布于 2022-09-11 20:48:07 字数 853 浏览 16 评论 0

#include <stdio.h>
#include <iostream>

using namespace std;

class CStr {
public:
    CStr(const char* pszTest) {
        if (NULL != pszTest) {
            int nLen = strlen(pszTest);
            m_pszTest = new char[nLen + 1];
            
            strcpy_s(m_pszTest,  nLen+1 , pszTest);
        }
        else {
            m_pszTest = new char[1];
            m_pszTest[0] = '\0';
        }
    }
    ~CStr() {
        if (NULL != m_pszTest) {
            delete[] m_pszTest;
            m_pszTest = NULL;
        }
    }
    
    void Show() {
        if (NULL != m_pszTest) {
            cout<<m_pszTest<<endl;
        }
    }

private:
    char *m_pszTest;
};

void TestFun(CStr s) {
    s.Show();
}

int main(  ) {
    CStr objS("TTs");
    TestFun(objS);
}

为什么这里程序会卡死,而且析构函数被调用了两次?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

深爱成瘾 2022-09-18 20:48:07

void TestFun(CStr s) ,这里的参数不是一个引用,因而参数传递的时候会发生一次拷贝,sobjS 会是两个不同的对象。

CStr 没有自定义拷贝构造函数,所以使用默认,m_pszTest 这个指针被拷贝了一份。

然后,sobjS 都需要析构,于是析构两次。

每次析构,都会 delete[] m_pszTest; 。由于 sobjS 是两个不同的对象,将s.m_pszTest 赋值为 NULL 并不会影响 objS.m_pszText (反之也是一样)。而 s.m_pszTestobjS.m_pszTest 的值原来是相同的(来自拷贝),于是这个地址被 delete[] 两次,引发未定义行为。

改成 void TestFun(CStr &s) 就好了,引用参数不发生拷贝。

==============
你这个类实际需要提供一个自定义的拷贝构造与自定义的赋值运算符,以保证在发生拷贝的时候不只是拷贝的指针的值,以避免重复 delete 。另见rule of three

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文