Ym影子
2018-01-30 09:18
采纳率: 100%
浏览 1.0k

关于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条回答 默认 最新

  • kongrenxin 2018-01-30 09:35
    已采纳

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

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

    已采纳该答案
    打赏 评论
  • mengzhisuoliu 2018-01-30 09:32

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

    打赏 评论
  • 鱼在沙漠 2018-01-30 09:41
    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);
    
    打赏 评论
  • kongrenxin 2018-01-30 09:44

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

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

    打赏 评论
  • 鱼在沙漠 2018-01-30 09:49

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

    打赏 评论

相关推荐 更多相似问题