关于C++ 函数参数为类对象时遇到的bug
 #define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;

class Teacher
{
private:

    static int constructor_count_null;
    static int constructor_count_two;
    static int constructor_count_copy;
    static int constructor_count_valuation;
    static int destructor_count;
    char* m_name;
    int m_age;
public:

    Teacher()
    {
        m_name = nullptr;
        m_age = 0;
        cout << "调用默认构造函数 " << ++constructor_count_null << "次" << endl;
    }
    Teacher(char*name,int age)
    {
        m_name = new char[strlen(name)];
        strcpy(m_name, name);
        m_age = age;
        cout << "调用有参构造函数 " << ++constructor_count_two << "次" << endl;
    }
    //析构函数
    ~Teacher()
    {
        delete []m_name;
        cout << "调用析构函数 " << ++destructor_count << "次" << endl;
    }
    //拷贝构造函数
    Teacher(const Teacher& t)
    {
        this->m_age = t.m_age;
        this->m_name = new char[strlen(t.m_name)];
        cout << &m_name << endl;
        strcpy(m_name, t.m_name);
        cout << "调用拷贝构造函数 " << ++constructor_count_copy << "次" << endl;
    }
    //重载赋值号
    Teacher& operator =(const Teacher&t)
    {
        //首先检测是不是重复赋值
        if(this!=&t)
        {
            //然后将原来的值delete
            if(this->m_name!=nullptr)
            {
                delete[]m_name;
                m_name = nullptr;
            }
            this->m_age = t.m_age;
            this->m_name = new char[strlen(t.m_name)];
            strcpy(m_name, t.m_name);
            cout << "使用重载过的赋值号 " << ++constructor_count_valuation << "次" << endl;
        }
        return *this;
    }
};

int Teacher::constructor_count_copy = 0;
int Teacher::constructor_count_null = 0;
int Teacher::constructor_count_two = 0;
int Teacher::constructor_count_valuation = 0;
int Teacher::destructor_count = 0;

//这个函数我想传入一个类
void func(Teacher  t)
{
}


int main( _In_ int argc, _In_reads_(argc) _Pre_z_ char** argv, _In_z_ char** envp )
{
    Teacher s("sss", 22);
    func(s);
    system("pause");
    return 0;
}

在debug模式下,会在func退出时出现bug,而在release中不会出现。
我的问题是:
为什么我明明做了深拷贝,debug模式下函数退出,析构匿名对象时会出错?

5个回答

m_name = new char[strlen(name) + 1];
this->m_name = new char[strlen(t.m_name) + 1];

改成如上两句就行了
在字符串分配空间的时候,需要多给一个字节,用来存放\0字符(因为strlen计算的长度是不包含\0的)。

this->m_name = new char[strlen(t.m_name)+sizeof(char)];即可

Teacher(char*name,int age)
{
    m_name = new char[strlen(name)];
    strcpy(m_name, name);
    m_age = age;
    cout << "调用有参构造函数 " << ++constructor_count_two << "次" << endl;
}
    这个构造函数的参数char *name,没有指定长度。strlen(name)的值并不能获取name字符串的长度,而是一个指针的长度(32位机器下为4字节),建议改为string name,这样可以通过name.length()获取长度;或者在参数中指定字符串的长度。
    如下:
    Teacher(char* name, int length ,int age)
{
    m_name = new char[length+1];
    strncpy(m_name, name, length);
    m_age = age;
    cout << "调用有参构造函数 " << ++constructor_count_two << "次" << endl;
}

    Teacher s("sss",3, 22);

楼上你别乱说,,, strlen是获取字符串的长度,只是不包含\0结尾字符。

你说的那个32bit指针大小为4,是sizeof,别搞混淆了。

qq_32378713
Ym影子 谢谢您的作答,非常的感谢!
接近 2 年之前 回复
zlin532
鱼在沙漠 嗯嗯
接近 2 年之前 回复

说错了,strlen(name)在这里用法没有问题,我看成sizeof了,问题在于数组长度应该+1。

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!