问题真的多 2022-04-11 19:38 采纳率: 25%
浏览 11
已结题

调用析构函数报错HEAP ERROR DETECTED

实现了一个字符串类Str.,然后重载运算符+和运算符=。在调用这两个构造函数的时候程序报错HEAP ERROR DETECTED。

img

类的实现如下

class String
{
public:
    String(const char* s="");
    String(const String& other);
    ~String();//拷贝构造函数
    String& operator=(const String& other);  //赋值运算符重载
    String& operator=(const char* s);//为字符串类直接赋值
    friend String operator+(String& s1, String& s2);
    void Display() const;//显示
    void Copy(const char* str);
private:
    char* s_;
};
#include "String.h"
#include<cstring>
#include<iostream>

using namespace std;
void String::Copy(const char* str)
{
    s_ = new char(strlen(str) + 1);
    strcpy_s(s_, strlen(str) + 1, str);
}
String::String(const char* s)
{
    Copy(s);
    cout << "Create " << s_ <<" by constructor" << endl;
}
String::String(const String& other)
{
    //delete s_;
    Copy(other.s_);
    cout << "Copy Constructor " << s_ << endl;
}
String::~String()
{
    cout << "Delete " << s_ << endl;
    delete s_;
}
void String::Display() const
{
    cout << s_ << endl;
}
String& String::operator=(const char* s)
{
    delete s_;
    Copy(s);
    return *this;
}
String& String::operator=(const String& other)
{
    if (this == &other)
        return *this;
    delete s_;
    Copy(other.s_);
    
    return *this;
}

String operator+(String& s1, String& s2)
{
    int n1 = strlen(s1.s_);
    int n2 = strlen(s2.s_);
    char* tmp = new char[n1 + n2 + 1];
    strcpy_s(tmp, n1 + 1, s1.s_);
    strcat_s(tmp, n1 + n2 + 1, s2.s_);
    return String(tmp);
}

测试代码如下:

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

using namespace std;

int main()
{

    String s1;
    s1 = "hello";
    s1.name = 1;
    String s2(" world");
    s2.name = 2;
    String s3;
    s3 = s1 + s2;
    s3.name = 3;
    return 0;
}

进一步调试发现,在执行代码s3 = s1 + s2时,operator+函数返回一个临时变量,然后通过拷贝构造函数赋值给s3,随后调用析构函数释放该临时变量,在调用析构函数时报错。
想不明白为什么这里报错,求解释,万分感谢!

  • 写回答

1条回答 默认 最新

  • 关注

    s_ = new char(strlen(str) + 1);
    这一句的含义是new申请一个char类型大小的空间,将该空间赋值为strlen(str) + 1,并返回值
    上面这句话等于下面这句话:
    s_=new char;
    *s_=strlen(str) + 1;
    因为C++允许对char赋整形值;
    而new 类型( 值)这种写法是在申请地址时构造;
    如果希望申请数组应该这么写:
    s_=new char[ strlen(str) + 1];
    释放空间时也要用对应的delete [] s_

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 4月21日
  • 已采纳回答 4月13日
  • 创建了问题 4月11日

悬赏问题

  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥15 (关键词-阻抗匹配,HFSS,RFID标签天线)
  • ¥15 机器人轨迹规划相关问题
  • ¥15 word样式右侧翻页键消失