【问题标题】:Can some one tell me whats worng with the bellow code(C++)?有人可以告诉我下面的代码(C++)有什么问题吗?
【发布时间】:2019-12-02 07:32:43
【问题描述】:

除非我没有为类定义析构函数,否则下面的代码可以正常工作。 但是当我定义析构函数时它会产生错误的结果。在析构函数部分,我释放了在构造函数中创建的内存。我认为这是我的工作。但在这种情况下,这样做会使我的程序以不需要的输出运行。我对这个计划感到非常沮丧。请帮帮我。我无法弄清楚代码有什么问题。一切对我来说似乎都还好。 在这里,我制作了一个列表类型的对象数组。然后我在构造函数的帮助下分别为对象赋值。但似乎这些值没有得到适当的初始化。但我认为初始化过程没有犯任何错误。然后,当我使用成员函数显示打印对象数据时,它无法产生所需的结果。尽管它正确打印了 int 和 float 数据成员。它无法正确打印 char* 数据成员。

#include <iostream>
#include <cstring>
#include <iomanip>
using namespace std;

class list
{
private:
    char*  name;
    int code;
    double cost;
public:
    //constructor
    list()
    {

    }
    list(const char* name,int code,double cost)
    {
        int len=strlen(name);
        this->name=new char[len+1];
        strcpy(this->name,name);
        this->code=code;
        this->cost=cost;

    }
    //mem fun
    void display(void)
    {
        cout.precision(2);
        cout.setf(ios::fixed);
        cout << setw(20) << this->name << setw(10) << this->code << setw      (12)    << cost << endl;
    }
    //destructor
    ~list()
    {
        delete[] this->name;
    }
};

int main()
{
    list item[3];

    item[0]=list("Turbo C++",1001,250.95);
    item[1]=list("C Primer",905,95.70);
    item[2]=list("C++ Book",105,30);

    cout << setw(20) << "NAME" << setw(10) << "CODE" << setw(12) << "COST"   <<     endl;

    for(int i=0;i<3;i++)
        item[i].display();

    return 0;
}

【问题讨论】:

  • 我收到了free(): double free detected in tcache 2 /srv/wrappers/cpp-clang: line 5: 31205 Aborted。您为默认构造的元素调用delete[],但您没有为它们调用new。使用标准容器,例如 std::stringstd::arraystd::vector
  • 关于为什么这段代码不起作用?的问题在 StackOverflow 上没有他们的位置。您的代码格式不正确,您没有提供任何错误或输出。另外,既然你不是在编写 C 语言,为什么不使用 std::string 举例呢?

标签: c++ constructor destructor dynamic-memory-allocation


【解决方案1】:

您正在复制所有列表项,因为您有一个对象数组(不是指针) - 因为它只是一个“浅拷贝”,所以您有两个实例具有相同的 name 指针,因此是“双重释放”消息.

有几种方法可以解决它:

  • 您可以定义一个operator= 来生成重复的字符串。那 工作,但你仍然有不必要的副本。
  • 您可以在main 中有一个指针数组(而不是实例)。
  • 您可以使用set() 方法在现有实例中设置值(例如item[0].set("Turbo C++", 1001, 250.95);

【讨论】:

  • 或者提供移动赋值运算符
  • 我没有得到你的答案。浅拷贝在哪里。 strcpy 不会做深拷贝吗?
  • @AyushMahajan strcpy 进行深层复制,但不会在 item[0]=list(...) 行中调用。它会被构造函数调用一次,但 = 只是在做一个字节复制,所以现在你有 2 个具有相同指针的对象 - 列表中的一个对象和用作赋值的 RHS 的匿名对象。跨度>
猜你喜欢
  • 1970-01-01
  • 2020-02-21
  • 2020-10-30
  • 2010-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
相关资源
最近更新 更多