这段代码为什么出错了?谁能解释的清楚一点呢


#include
#include
using std::string;
class hstring
{
private:
     char* c_str;
public:
    hstring( )  
    {
        c_str = new char[1]{0};
    }
    hstring(const char* _str)
    {
        c_str=(char*)_str;
    }
    char* show( ) const
    {
        return c_str;
    }
    ~hstring()
    {
        delete[] c_str;
    }
};
int main()
{
    hstring str("你好");
    std::cout << str.show();
    system("pause");
}
这段代码为什么出错了?谁能解释的清楚一点呢

c_str=(char*)_str;
你这里不是动态分配的
后面delete了

    hstring(const char* _str)
    {
        c_str = new char[strlen(_str) + 1];
        strcpy(c_str, _str);
    }

这段代码中有一个问题。在 hstring 类的构造函数中,c_str 被赋值为 _str 的地址。但是,_str 是一个指向常量字符的指针,它指向的内存区域是只读的。当 hstring 类的析构函数被调用时,它试图删除 c_str 指向的内存,但是这是不允许的,因为这块内存是只读的。这会导致运行时错误。

要解决这个问题,可以在 hstring 类的构造函数中分配足够的内存来存储 _str 中的字符串,并使用 strcpy 函数将字符串复制到新分配的内存中。这样,在析构函数中删除 c_str 指向的内存就不会有问题了。

#include<iostream>
#include<string>
#include<cstring>
using std::string;
class hstring
{
private:
     char* c_str;
public:
    hstring( )  
    {
        c_str = new char[1]{0};
    }
    hstring(const char* _str)
    {
        c_str = new char[strlen(_str) + 1];
        strcpy(c_str, _str);
    }
    char* show( ) const
    {
        return c_str;
    }
    ~hstring()
    {
        delete[] c_str;
    }
};
int main()
{
    hstring str("你好");
    std::cout << str.show();
    system("pause");
}

  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7562864
  • 你也可以参考下这篇文章:如何按逆顺序输出一个多位数各个位上的数字?
  • 除此之外, 这篇博客: 为什么不建议函数有太多参数?中的 观察参数传递方式 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 我做了一个实验,观察对含有6个、7个、8个参数的函数进行调用时,到底有哪些不同,测试代码如下:

    #include <iostream>
    
    void func6(int p1, int p2, int p3, int p4, int p5,
               int p6)
    {
    }
    
    void func7(int p1, int p2, int p3, int p4, int p5,
               int p6, int p7)
    {
    }
    
    void func8(int p1, int p2, int p3, int p4, int p5,
               int p6, int p7, int p8)
    {
    }
    
    int main()
    {
        func6(1, 2, 3, 4, 5, 6);
        func7(1, 2, 3, 4, 5, 6, 7);
        func8(1, 2, 3, 4, 5, 6, 7, 8);
        return 0;
    }
    

    我们查看汇编代码,来观察调用时如何传递参数。

    我们看一下func6的调用,全部通过寄存器传递。

       0x00005555555551ce <+8>:     mov    r9d,0x6
       0x00005555555551d4 <+14>:    mov    r8d,0x5
       0x00005555555551da <+20>:    mov    ecx,0x4
       0x00005555555551df <+25>:    mov    edx,0x3
       0x00005555555551e4 <+30>:    mov    esi,0x2
       0x00005555555551e9 <+35>:    mov    edi,0x1
       0x00005555555551ee <+40>:    call   0x555555555169 <func6(int, int, int, int, int, int)>
    

    我们看一下func7的调用,参数1~6通过寄存器,参数7通过堆栈传递。

    
       0x00005555555551f3 <+45>:    push   0x7
       0x00005555555551f5 <+47>:    mov    r9d,0x6
       0x00005555555551fb <+53>:    mov    r8d,0x5
       0x0000555555555201 <+59>:    mov    ecx,0x4
       0x0000555555555206 <+64>:    mov    edx,0x3
       0x000055555555520b <+69>:    mov    esi,0x2
       0x0000555555555210 <+74>:    mov    edi,0x1
       0x0000555555555215 <+79>:    call   0x555555555188 <func7(int, int, int, int, int, int, int)>
    

    我们看一下func8的调用,参数16通过寄存器,参数78通过堆栈传递。

       0x000055555555521e <+88>:    push   0x8
       0x0000555555555220 <+90>:    push   0x7
       0x0000555555555222 <+92>:    mov    r9d,0x6
       0x0000555555555228 <+98>:    mov    r8d,0x5
       0x000055555555522e <+104>:   mov    ecx,0x4
       0x0000555555555233 <+109>:   mov    edx,0x3
       0x0000555555555238 <+114>:   mov    esi,0x2
       0x000055555555523d <+119>:   mov    edi,0x1
       0x0000555555555242 <+124>:   call   0x5555555551a7 <func8(int, int, int, int, int, int, int, int)>
    

  • 您还可以看一下 千锋老师的什么是云计算? 课程中的 杨哥知识普及小课堂之 什么是云计算?小节, 巩固相关知识点