#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");
}
我做了一个实验,观察对含有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)>