Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.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++ 构造函数和运算符=具有动态内存分配_C++_Crash_Copy Constructor_Dynamic Memory Allocation_Assignment Operator - Fatal编程技术网

C++ 构造函数和运算符=具有动态内存分配

C++ 构造函数和运算符=具有动态内存分配,c++,crash,copy-constructor,dynamic-memory-allocation,assignment-operator,C++,Crash,Copy Constructor,Dynamic Memory Allocation,Assignment Operator,这里没有。我正在做一本书中的练习,编译器没有报告任何错误,但当我试图运行它时,程序崩溃了 我试着运行一个小程序来练习Cow类的不同方法。它显式具有:构造函数、默认构造函数、复制构造函数、析构函数、重载赋值运算符和显示其内容的方法 我将把整个项目: 类别规格: //cow.h -- For project Exercise 12.1.cbp class Cow { char name[20]; // memory is allocated in the stack char *h

这里没有。我正在做一本书中的练习,编译器没有报告任何错误,但当我试图运行它时,程序崩溃了

我试着运行一个小程序来练习Cow类的不同方法。它显式具有:构造函数、默认构造函数、复制构造函数、析构函数、重载赋值运算符和显示其内容的方法

我将把整个项目:

类别规格:

//cow.h -- For project Exercise 12.1.cbp

class Cow
{
    char name[20]; // memory is allocated in the stack
    char *hobby;
    double weight;
public:
    Cow();
    Cow(const char *nm, const char *ho, double wt);
    Cow(const Cow &c);
    ~Cow();
    Cow & operator=(const Cow &c);
    void ShowCow() const; // display all cow data
};
实施方法:

// cow.cpp -- Cow class methods implementation (compile with main.cpp)

#include <cstring>
#include <iostream>
#include "cow.h"

Cow::Cow() // default destructor
{
    strcpy(name, "empty");
    hobby = new char[6]; // makes it compatible with delete[]
    strcpy(hobby, "empty");
    weight = 0.0;
}

Cow::Cow(const char *nm, const char *ho, double wt)
{
    strcpy(name, nm); // name = nm; is wrong, it copies the address of the argument pointer (swallow copying)
    /*if (name[20] != '\0') // if it's not a string, make it a string (in case nm is larger than 20)
        name[20] = '\0';*/
    hobby = new char[strlen(ho) + 1]; // allocates the needed memory to hold the argument string
    strcpy(hobby, ho); // copies the pointed-to data from the argument pointer to the class pointer
    weight = wt;
}

Cow::Cow(const Cow &c) // copy constructor
{
    strcpy(name, c.name); // copies the value to the desired address
    char *temp = hobby; // stores the address of the memory previously allocated with new
    hobby = new char[strlen(c.hobby) + 1];
    strcpy(hobby, c.hobby); // copies the value to the new address
    delete[] temp; // deletes the previously new allocated memory
    weight = c.weight;
}

Cow::~Cow()
{
    delete[] hobby;
}

Cow & Cow::operator=(const Cow &c) // overloaded assignment operator
{
    strcpy(name, c.name);
    char *temp = hobby;
    hobby = new char[strlen(c.hobby) + 1];
    strcpy(hobby, c.hobby);
    delete[] temp;
    weight = c.weight;
    return *this;
}

void Cow::ShowCow() const
{
    std::cout << "Name: " << name << '\n';
    std::cout << "Hobby: " << hobby << '\n';
    std::cout << "Weight: " << weight << "\n\n";
}
特别是在重载赋值运算符和复制构造函数中,如果我隐藏
delete[]temp
行,程序不会崩溃

我是一个彻头彻尾的傻瓜,可能有点愚蠢,但我看不出在这些定义中我做错了什么

有什么帮助吗

Cow::Cow(const Cow &c) // copy constructor
{
    strcpy(name, c.name); // copies the value to the desired address
    char *temp = hobby; // stores the address of the memory previously allocated with new
    hobby = new char[strlen(c.hobby) + 1];
    strcpy(hobby, c.hobby); // copies the value to the new address
    delete[] temp; // deletes the previously new allocated memory
    weight = c.weight;
}
这是副本c-tor。没有以前分配的成员<代码>此->爱好指向随机垃圾。因此,当你
在新作业之前删除[]temp
(即
这个->爱好
)时,你会得到UB

Cow & Cow::operator=(const Cow &c) // overloaded assignment operator
{
    strcpy(name, c.name);
    char *temp = hobby;
    hobby = new char[strlen(c.hobby) + 1];
    strcpy(hobby, c.hobby);
    delete[] temp;
    hobby = name;
    weight = c.weight;
    return *this;
}

hobby=name
不正确,因为它会导致内存泄漏+析构函数将尝试删除未使用
运算符new[]

@分配的对象。ForEveR已经注意到,复制构造函数正在删除从未分配的内存

但是我会说整个练习都有缺陷,用C语言教C,而不是C++。如果您使用字符串,所有的问题都会消失,因为您不必直接管理资源。这样就不需要完全编写析构函数或复制赋值/构造函数。例如:

class Cow
{
    std::string name;
    std::string hobby;
    double weight;
public:
    Cow();
    Cow(const std::string& nm, const std::string& ho, double wt);
    void ShowCow() const; // display all cow data
};

在C++中,通常不编写这样的赋值操作符,因为它们与复制构造函数非常相似,因此大多是重复代码。我建议你看看@dialer谢谢你的建议!现在,我正在阅读一本书,书中采用了一种真正有条理的逐件方法。但我会看看的。谢谢你的帮助!实际上,这是一个真正的noob错误,将构造函数当作赋值运算符来尝试。第二个错误是我的一个助手在破译我添加代码的错误,那行不应该在那里。谢谢你的时间!谢谢你的回答。问题是作者已经知道这一点。事实上,前面的一个练习涉及创建一个StringBad类来模拟(以简化的方式)标准字符串行为。我知道字符串已经不存在了,但它只是专门针对类实践动态内存分配。
Cow & Cow::operator=(const Cow &c) // overloaded assignment operator
{
    strcpy(name, c.name);
    char *temp = hobby;
    hobby = new char[strlen(c.hobby) + 1];
    strcpy(hobby, c.hobby);
    delete[] temp;
    hobby = name;
    weight = c.weight;
    return *this;
}
class Cow
{
    std::string name;
    std::string hobby;
    double weight;
public:
    Cow();
    Cow(const std::string& nm, const std::string& ho, double wt);
    void ShowCow() const; // display all cow data
};